Commit b6eeb85e authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Refactoring ParaView application settings dialog.

Added new class pqSettingsDialog which is a settings dialog constructed
by scanning all proxies registered under the "options" group. Created a
new proxy ("options", "GeneralSettings") that is created during session
initialization by vtkSMParaViewPipelineController. This keeps track of
the general application settings for ParaView.

Added mechanism in pqProxyWidget to look a "hint" on the proxy which
says that the documentation should be used for labelling the widgets.
Using that for the GeneralSettings proxy to construct a verbose settings
panel. Currently, on pqIntVectorPropertyWidget respects that setting
when construting label on its own. Otherwise, it works only when the
pqPropertyWidget doesn't render the label on its own.

Change-Id: Ide52f736748ab7a234307ab0b801b008de4e5703
parent eb43d5e2
......@@ -94,10 +94,10 @@ bool pq@BPC_NAME@Initializer::Initialize(int argc, char* argv[])
pqSettings *settings = this->PVApp->settings();
bool show_splash = false;
if (!this->PVApp->getOptions()->GetDisableRegistry() &&
settings->value("disableSplashScreen", true).toBool() == false)
if (!this->PVApp->getOptions()->GetDisableRegistry())
{
show_splash = true;
show_splash = settings->value(
"GeneralSettings.ShowSplashScreen", false).toBool();
}
if(show_splash)
......
......@@ -435,6 +435,18 @@ bool vtkSMParaViewPipelineController::InitializeSession(vtkSMSession* session)
proxy->Delete();
}
proxy = pxm->GetProxy("options", "GeneralSettings");
if (!proxy)
{
proxy = pxm->NewProxy("options", "GeneralSettings");
if (proxy)
{
this->InitializeProxy(proxy);
pxm->RegisterProxy("options", "GeneralSettings", proxy);
proxy->UpdateVTKObjects();
proxy->Delete();
}
}
//---------------------------------------------------------------------------
// Setup color palette and proxies for other global property groups (optional)
proxy = pxm->GetProxy("global_properties", "ColorPalette");
......@@ -1255,6 +1267,7 @@ bool vtkSMParaViewPipelineController::ResetSession(vtkSMSession* session)
// Now create new time-animation track.
this->InitializeSession(session);
return true;
}
//----------------------------------------------------------------------------
......
......@@ -15,7 +15,10 @@
#include "vtkSMPropertyGroup.h"
#include "vtkObjectFactory.h"
#include "vtkPVXMLElement.h"
#include "vtkSMDocumentation.h"
#include "vtkSMProperty.h"
#include "vtkSMProxy.h"
#include "vtkWeakPointer.h"
#include <map>
......@@ -42,6 +45,8 @@ vtkSMPropertyGroup::vtkSMPropertyGroup()
// by default, properties are set to always shown
this->SetPanelVisibility("default");
this->Documentation = vtkSMDocumentation::New();
}
//---------------------------------------------------------------------------
......@@ -52,6 +57,8 @@ vtkSMPropertyGroup::~vtkSMPropertyGroup()
this->SetPanelWidget(0);
this->SetPanelVisibility(0);
delete this->Internals;
this->Documentation->Delete();
this->Documentation = NULL;
}
//---------------------------------------------------------------------------
......@@ -119,3 +126,79 @@ const char* vtkSMPropertyGroup::GetFunction(vtkSMProperty* property) const
}
return NULL;
}
//---------------------------------------------------------------------------
int vtkSMPropertyGroup::ReadXMLAttributes(
vtkSMProxy* proxy, vtkPVXMLElement* groupElem)
{
if (!proxy || !groupElem)
{
return 0;
}
// FIXME: should we use group-name as the "key" for the property groups?
const char *groupName = groupElem->GetAttribute("name");
if(groupName)
{
this->SetName(groupName);
}
const char *groupLabel = groupElem->GetAttribute("label");
if(groupLabel)
{
this->SetXMLLabel(groupLabel);
}
// this is deprecated attribute that's replaced by "panel_widget". We still
// process it for backwards compatibility.
const char *groupType = groupElem->GetAttribute("type");
if(groupType)
{
vtkWarningMacro("Found deprecated attribute 'type' of PropertyGroup. "
"Please use 'panel_widget' instead.");
this->SetPanelWidget(groupType);
}
groupType = groupElem->GetAttribute("panel_widget");
if(groupType)
{
this->SetPanelWidget(groupType);
}
const char *panelVisibility = groupElem->GetAttribute("panel_visibility");
if(panelVisibility)
{
this->SetPanelVisibility(panelVisibility);
}
for (unsigned int k = 0; k < groupElem->GetNumberOfNestedElements(); k++)
{
vtkPVXMLElement* elem = groupElem->GetNestedElement(k);
if (elem->GetName() && strcmp(elem->GetName(), "Documentation") == 0)
{
this->Documentation->SetDocumentationElement(elem);
continue;
}
// if elem has "exposed_name", use that to locate the property, else use the
// "name".
const char* propname = elem->GetAttribute("exposed_name")?
elem->GetAttribute("exposed_name") : elem->GetAttribute("name");
vtkSMProperty* property = propname? proxy->GetProperty(propname) : NULL;
if (!property)
{
vtkWarningMacro("Failed to locate property '" <<
(propname? propname : "(none)") << "' for PropertyGroup. Skipping.");
}
else
{
const char* functionAttribute = elem->GetAttribute("function");
if (functionAttribute == 0)
{
functionAttribute = elem->GetAttribute("name");
}
this->AddProperty(functionAttribute, property);
}
}
return 1;
}
......@@ -19,8 +19,11 @@
#include "vtkPVServerManagerCoreModule.h" //needed for exports
#include "vtkSMObject.h"
class vtkPVXMLElement;
class vtkSMDocumentation;
class vtkSMProperty;
class vtkSMPropertyGroupInternals;
class vtkSMProxy;
class VTKPVSERVERMANAGERCORE_EXPORT vtkSMPropertyGroup : public vtkSMObject
{
......@@ -88,10 +91,18 @@ public:
// Returns the number of properties in the group.
unsigned int GetNumberOfProperties() const;
// Description:
// Returns the documentation for this proxy.
vtkGetObjectMacro(Documentation, vtkSMDocumentation);
protected:
vtkSMPropertyGroup();
~vtkSMPropertyGroup();
friend class vtkSMProxy;
virtual int ReadXMLAttributes(vtkSMProxy* parent, vtkPVXMLElement* element);
vtkSMDocumentation* Documentation;
private:
vtkSMPropertyGroup(const vtkSMPropertyGroup&); // Not implemented
void operator=(const vtkSMPropertyGroup&); // Not implemented
......
......@@ -1463,67 +1463,13 @@ vtkSMProperty* vtkSMProxy::NewProperty(const char* name,
vtkSMPropertyGroup* vtkSMProxy::NewPropertyGroup(vtkPVXMLElement* groupElem)
{
vtkSMPropertyGroup *group = vtkSMPropertyGroup::New();
// FIXME: should we use group-name as the "key" for the property groups?
const char *groupName = groupElem->GetAttribute("name");
if(groupName)
{
group->SetName(groupName);
}
const char *groupLabel = groupElem->GetAttribute("label");
if(groupLabel)
{
group->SetXMLLabel(groupLabel);
}
// this is deprecated attribute that's replaced by "panel_widget". We still
// process it for backwards compatibility.
const char *groupType = groupElem->GetAttribute("type");
if(groupType)
{
vtkWarningMacro("Found deprecated attribute 'type' of PropertyGroup. "
"Please use 'panel_widget' instead.");
group->SetPanelWidget(groupType);
}
groupType = groupElem->GetAttribute("panel_widget");
if(groupType)
{
group->SetPanelWidget(groupType);
}
const char *panelVisibility = groupElem->GetAttribute("panel_visibility");
if(panelVisibility)
if (!group->ReadXMLAttributes(this, groupElem))
{
group->SetPanelVisibility(panelVisibility);
}
for (unsigned int k = 0; k < groupElem->GetNumberOfNestedElements(); k++)
{
vtkPVXMLElement* elem = groupElem->GetNestedElement(k);
// if elem has "exposed_name", use that to locate the property, else use the
// "name".
const char* propname = elem->GetAttribute("exposed_name")?
elem->GetAttribute("exposed_name") : elem->GetAttribute("name");
vtkSMProperty* property = propname? this->GetProperty(propname) : NULL;
if (!property)
{
vtkWarningMacro("Failed to locate property '" <<
(propname? propname : "(none)") << "' for PropertyGroup. Skipping.");
}
else
{
const char* functionAttribute = elem->GetAttribute("function");
if (functionAttribute == 0)
{
functionAttribute = elem->GetAttribute("name");
}
group->AddProperty(functionAttribute, property);
}
group->Delete();
return NULL;
}
// FIXME: should we use group-name as the "key" for the property groups?
this->Internals->PropertyGroups.push_back(group);
group->Delete();
......
......@@ -99,15 +99,16 @@ target_link_libraries(vtkPVServerManagerApplication
# Setup SM xmls.
#------------------------------------------------------------------------------
SET(requestedResourceFiles
${CMAKE_CURRENT_SOURCE_DIR}/Resources/3d_widgets.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/catalyst.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/filters.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/sources.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/internal_writers.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/options.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/readers.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/utilities.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/rendering.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/sources.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/utilities.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/views_and_representations.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/3d_widgets.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/internal_writers.xml
${CMAKE_CURRENT_SOURCE_DIR}/Resources/writers.xml
${module_sm_xmls}
)
......
<ServerManagerConfiguration>
<ProxyGroup name="options">
<Proxy name="GeneralSettings" label="General Settings">
<Documentation>
Collection of general setting for ParaView.
</Documentation>
<IntVectorProperty name="ShowSplashScreen"
number_of_elements="1"
default_values="0">
<Documentation>
Show splash screen at startup.
</Documentation>
<BooleanDomain name="bool" />
<Hints>
<SaveInQSettings />
</Hints>
</IntVectorProperty>
<IntVectorProperty name="CrashRecovery"
number_of_elements="1"
default_values="0">
<Documentation>
On a crash, attempt to save a state file to potentially restore
the application state to that before the crash.
</Documentation>
<BooleanDomain name="bool" />
<Hints>
<SaveInQSettings />
</Hints>
</IntVectorProperty>
<StringVectorProperty name="DefaultViewType"
number_of_elements="1"
default_values="Render View">
<Documentation>
Set the view to create when ParaView starts up.
</Documentation>
<StringListDomain name="list">
<String value="Render View" />
<String value="Line Chart View" />
</StringListDomain>
</StringVectorProperty>
<IntVectorProperty name="AutoApply"
number_of_elements="1"
default_values="0">
<Documentation>
Automatically apply changes in the 'Properties' panel.
</Documentation>
<BooleanDomain name="bool" />
</IntVectorProperty>
<IntVectorProperty name="AutoApplyActiveOnly"
number_of_elements="1"
default_values="0">
<Documentation>
Limit automatic accepting of changes on the 'Properties'
panel to the active panel alone.
</Documentation>
<BooleanDomain name="bool" />
</IntVectorProperty>
<IntVectorProperty name="AutoConvertProperties"
number_of_elements="1"
default_values="0">
<Documentation>
Automatically convert data arrays as needed by filters including converting
cell arrays to point arrays, or vice versa, and extracting single components
from multi-component arrays.
</Documentation>
<BooleanDomain name="bool"/>
</IntVectorProperty>
<IntVectorProperty name="StrictLoadBalancing"
number_of_elements="1"
default_values="0">
<Documentation>
Use strict load balancing for structured datasets (fixme: need to
figure out what this one does).
</Documentation>
<BooleanDomain name="bool"/>
</IntVectorProperty>
<IntVectorProperty name="DefaultTimeStep"
number_of_elements="1"
default_values="1">
<Documentation>
Any time a new dataset with timesteps is opened,
set the timestep the application should go to
by default.
</Documentation>
<EnumerationDomain name="enum">
<Entry text="Leave current time unchanged, if possible" value="0" />
<Entry text="Go to first timestep" value="1" />
<Entry text="Go to last timestep" value="2" />
</EnumerationDomain>
</IntVectorProperty>
<IntVectorProperty name="EnableAutoMPI"
number_of_elements="1"
default_values="0">
<Documentation>
Enable multicore support for data processing.
</Documentation>
<BooleanDomain name="bool" />
</IntVectorProperty>
<IntVectorProperty name="AutoMPILimit"
number_of_elements="1"
default_values="2">
<Documentation>
Limit maximum number of cores to
</Documentation>
<IntRangeDomain min="1" max="64" />
</IntVectorProperty>
<PropertyGroup label="General Options">
<Property name="ShowSplashScreen" />
<Property name="CrashRecovery" />
</PropertyGroup>
<PropertyGroup label="Properties Panel Options">
<Property name="AutoApply" />
<Property name="AutoApplyActiveOnly" />
</PropertyGroup>
<PropertyGroup label="Data Processing Options">
<Property name="AutoConvertProperties" />
<Property name="StrictLoadBalancing" />
</PropertyGroup>
<PropertyGroup label="Multicore Support">
<Documentation>
On multicore systems, ParaView can run parallel pvserver processes automatically,
without you having to launch them manually for processing data in parallel.
</Documentation>
<Property name="EnableAutoMPI" />
<Property name="AutoMPILimit" />
</PropertyGroup>
<Hints>
<UseDocumentationForLabels />
</Hints>
</Proxy>
</ProxyGroup>
</ServerManagerConfiguration>
......@@ -31,11 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
========================================================================*/
#include "pqApplicationSettingsReaction.h"
#include "pqApplicationOptionsDialog.h"
#include "pqSettingsDialog.h"
#include "pqCoreUtilities.h"
QPointer<pqApplicationOptionsDialog> pqApplicationSettingsReaction::Dialog;
QPointer<pqSettingsDialog> pqApplicationSettingsReaction::Dialog;
//-----------------------------------------------------------------------------
pqApplicationSettingsReaction::pqApplicationSettingsReaction(QAction* parentObject)
......@@ -54,10 +54,10 @@ void pqApplicationSettingsReaction::showApplicationSettingsDialog()
{
if (!pqApplicationSettingsReaction::Dialog)
{
pqApplicationSettingsReaction::Dialog = new pqApplicationOptionsDialog(
pqApplicationSettingsReaction::Dialog = new pqSettingsDialog(
pqCoreUtilities::mainWidget());
pqApplicationSettingsReaction::Dialog->setObjectName("ApplicationSettings");
pqApplicationSettingsReaction::Dialog->setAttribute(Qt::WA_QuitOnClose, false);
pqApplicationSettingsReaction::Dialog->setAttribute(Qt::WA_QuitOnClose, true);
}
pqApplicationSettingsReaction::Dialog->show();
pqApplicationSettingsReaction::Dialog->raise();
......
......@@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqReaction.h"
#include <QPointer>
class pqApplicationOptionsDialog;
class pqSettingsDialog;
/// @ingroup Reactions
/// pqApplicationSettingsReaction is a reaction to popup the application
/// settings dialog. It creates pqApplicationOptionsDialog when required.
/// settings dialog. It creates pqSettingsDialog when required.
class PQAPPLICATIONCOMPONENTS_EXPORT pqApplicationSettingsReaction : public pqReaction
{
Q_OBJECT
......@@ -60,7 +60,7 @@ protected:
private:
Q_DISABLE_COPY(pqApplicationSettingsReaction)
static QPointer<pqApplicationOptionsDialog> Dialog;
static QPointer<pqSettingsDialog> Dialog;
};
#endif
......
......@@ -335,6 +335,8 @@ set (Module_SRCS
pqServerConnectDialog.h
pqServerLauncher.cxx
pqServerLauncher.h
pqSettingsDialog.cxx
pqSettingsDialog.h
pqSignalAdaptorCompositeTreeWidget.cxx
pqSignalAdaptorCompositeTreeWidget.h
pqSignalAdaptorKeyFrameType.cxx
......@@ -552,6 +554,7 @@ set (Module_MOC_HDRS
pqServerConfigurationImporter.h
pqServerConnectDialog.h
pqServerLauncher.h
pqSettingsDialog.h
pqSignalAdaptorCompositeTreeWidget.h
pqSignalAdaptorKeyFrameType.h
pqSignalAdaptorSelectionTreeWidget.h
......@@ -656,6 +659,7 @@ set (Module_UI_FILES
Resources/UI/pqSelectReaderDialog.ui
Resources/UI/pqServerConnectDialog.ui
Resources/UI/pqServerLauncherDialog.ui
Resources/UI/pqSettingsDialog.ui
Resources/UI/pqSphereWidget.ui
Resources/UI/pqSplineWidget.ui
Resources/UI/pqSpreadSheetDisplayEditor.ui
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>513</width>
<height>560</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabBar" name="tabWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page"/>
<widget class="QWidget" name="page_2"/>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::RestoreDefaults</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QTabBar</class>
<extends>QWidget</extends>
<header location="global">QTabBar</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -24,6 +24,9 @@
#include "pqStandardViewModules.h"
#include "vtkProcessModule.h"
#include <QToolBar>
#include <QAction>
MainPipelineWindow::MainPipelineWindow()
{
// Init ParaView
......@@ -64,6 +67,12 @@ MainPipelineWindow::MainPipelineWindow()
createPipelineWithAnnotation(server);
QTimer::singleShot(100, this, SLOT(processTest()));
QToolBar *tb = new QToolBar("Options", this);
this->addToolBar(tb);
QAction* actn = tb->addAction("Settings");
this->connect(actn, SIGNAL(triggered()), SLOT(showSettings()));
}
//-----------------------------------------------------------------------------
......@@ -155,6 +164,23 @@ void MainPipelineWindow::createPipelineWithAnnotation(pqServer* server)
append->getProxy()->SetAnnotation("tooltip", "2+3");
groupDS->getProxy()->SetAnnotation("tooltip", "2");
}
#include "pqActiveObjects.h"
#include "pqProxyWidgetDialog.h"
#include "vtkSMSessionProxyManager.h"
//-----------------------------------------------------------------------------
void MainPipelineWindow::showSettings()
{
pqServer* server = pqActiveObjects::instance().activeServer();
vtkSMSessionProxyManager* pxm = server->proxyManager();
vtkSMProxy* optionsProxy = pxm->NewProxy("options", "GeneralSettings");
pqProxyWidgetDialog dialog(optionsProxy, this);
dialog.exec();
optionsProxy->Delete();
}
//-----------------------------------------------------------------------------
int main(int argc, char** argv)
{
......
......@@ -25,5 +25,5 @@ protected:
public slots:
void processTest();
void updateSelectedFilter(int);
void showSettings();
};
......@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqIntRangeWidget.h"
#include "pqLineEdit.h"
#include "pqProxyWidget.h"
#include "pqSignalAdaptorCompositeTreeWidget.h"
#include "pqSignalAdaptorSelectionTreeWidget.h"
#include "pqSignalAdaptors.h"
......@@ -55,6 +56,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QComboBox>
#include <QHBoxLayout>
#include <QIntValidator>
#include <QLabel>
pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(vtkSMProperty *smproperty,
vtkSMProxy *smProxy,
......@@ -68,7 +70,9 @@ pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(vtkSMProperty *smproperty,
{
return;
}
bool useDocumentationForLabels = pqProxyWidget::useDocumentationForLabels(smProxy);
// find the domain
vtkSmartPointer<vtkSMDomain> domain;
vtkSMDomainIterator *domainIter = ivp->NewDomainIterator();
......@@ -88,12 +92,21 @@ pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(vtkSMProperty *smproperty,
if(vtkSMBooleanDomain::SafeDownCast(domain))
{
QCheckBox *checkBox = new QCheckBox(smproperty->GetXMLLabel(), this);
QCheckBox *checkBox = new QCheckBox(
useDocumentationForLabels? "" : smproperty->GetXMLLabel(), this);
checkBox->setObjectName("CheckBox");
this->addPropertyLink(checkBox, "checked", SIGNAL(toggled(bool)), ivp);
this->setChangeAvailableAsChangeFinished(true);
layoutLocal->addWidget(checkBox);
if (useDocumentationForLabels)
{
QLabel* label = new QLabel(
QString("<p>%1</p>").arg(pqProxyWidget::documentationText(smproperty)));
label->setWordWrap(true);
label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
layoutLocal->addWidget(label, /*stretch=*/1);