Files
create/src/Mod/Plot/plotAxes/TaskPanel.py
2018-12-08 11:27:22 -03:00

648 lines
27 KiB
Python

#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* This program is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with this program; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#***************************************************************************
import FreeCAD as App
import FreeCADGui as Gui
from PySide import QtGui, QtCore
import Plot
from plotUtils import Paths
class TaskPanel:
def __init__(self):
self.ui = Paths.modulePath() + "/plotAxes/TaskPanel.ui"
self.skip = False
def accept(self):
return True
def reject(self):
return True
def clicked(self, index):
pass
def open(self):
pass
def needsFullSpace(self):
return True
def isAllowedAlterSelection(self):
return False
def isAllowedAlterView(self):
return True
def isAllowedAlterDocument(self):
return False
def helpRequested(self):
pass
def setupUi(self):
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
self.form = form
form.axId = self.widget(QtGui.QSpinBox, "axesIndex")
form.new = self.widget(QtGui.QPushButton, "newAxesButton")
form.remove = self.widget(QtGui.QPushButton, "delAxesButton")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xMin = self.widget(QtGui.QSlider, "posXMin")
form.xMax = self.widget(QtGui.QSlider, "posXMax")
form.yMin = self.widget(QtGui.QSlider, "posYMin")
form.yMax = self.widget(QtGui.QSlider, "posYMax")
form.xAlign = self.widget(QtGui.QComboBox, "xAlign")
form.yAlign = self.widget(QtGui.QComboBox, "yAlign")
form.xOffset = self.widget(QtGui.QSpinBox, "xOffset")
form.yOffset = self.widget(QtGui.QSpinBox, "yOffset")
form.xAuto = self.widget(QtGui.QCheckBox, "xAuto")
form.yAuto = self.widget(QtGui.QCheckBox, "yAuto")
form.xSMin = self.widget(QtGui.QLineEdit, "xMin")
form.xSMax = self.widget(QtGui.QLineEdit, "xMax")
form.ySMin = self.widget(QtGui.QLineEdit, "yMin")
form.ySMax = self.widget(QtGui.QLineEdit, "yMax")
self.retranslateUi()
# Look for active axes if can
axId = 0
plt = Plot.getPlot()
if plt:
while plt.axes != plt.axesList[axId]:
axId = axId + 1
form.axId.setValue(axId)
self.updateUI()
QtCore.QObject.connect(form.axId,
QtCore.SIGNAL('valueChanged(int)'),
self.onAxesId)
QtCore.QObject.connect(form.new,
QtCore.SIGNAL("pressed()"),
self.onNew)
QtCore.QObject.connect(form.remove,
QtCore.SIGNAL("pressed()"),
self.onRemove)
QtCore.QObject.connect(form.xMin,
QtCore.SIGNAL("valueChanged(int)"),
self.onDims)
QtCore.QObject.connect(form.xMax,
QtCore.SIGNAL("valueChanged(int)"),
self.onDims)
QtCore.QObject.connect(form.yMin,
QtCore.SIGNAL("valueChanged(int)"),
self.onDims)
QtCore.QObject.connect(form.yMax,
QtCore.SIGNAL("valueChanged(int)"),
self.onDims)
QtCore.QObject.connect(form.xAlign,
QtCore.SIGNAL("currentIndexChanged(int)"),
self.onAlign)
QtCore.QObject.connect(form.yAlign,
QtCore.SIGNAL("currentIndexChanged(int)"),
self.onAlign)
QtCore.QObject.connect(form.xOffset,
QtCore.SIGNAL("valueChanged(int)"),
self.onOffset)
QtCore.QObject.connect(form.yOffset,
QtCore.SIGNAL("valueChanged(int)"),
self.onOffset)
QtCore.QObject.connect(form.xAuto,
QtCore.SIGNAL("stateChanged(int)"),
self.onScales)
QtCore.QObject.connect(form.yAuto,
QtCore.SIGNAL("stateChanged(int)"),
self.onScales)
QtCore.QObject.connect(form.xSMin,
QtCore.SIGNAL("editingFinished()"),
self.onScales)
QtCore.QObject.connect(form.xSMax,
QtCore.SIGNAL("editingFinished()"),
self.onScales)
QtCore.QObject.connect(form.ySMin,
QtCore.SIGNAL("editingFinished()"),
self.onScales)
QtCore.QObject.connect(form.ySMax,
QtCore.SIGNAL("editingFinished()"),
self.onScales)
QtCore.QObject.connect(
Plot.getMdiArea(),
QtCore.SIGNAL("subWindowActivated(QMdiSubWindow*)"),
self.onMdiArea)
return False
def getMainWindow(self):
toplevel = QtGui.QApplication.topLevelWidgets()
for i in toplevel:
if i.metaObject().className() == "Gui::MainWindow":
return i
raise RuntimeError("No main window found")
def widget(self, class_id, name):
"""Return the selected widget.
Keyword arguments:
class_id -- Class identifier
name -- Name of the widget
"""
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
return form.findChild(class_id, name)
def retranslateUi(self):
"""Set the user interface locale strings.
"""
form = self.form
form.setWindowTitle(QtGui.QApplication.translate(
"plot_axes",
"Configure axes",
None))
self.widget(QtGui.QLabel, "axesLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Active axes",
None))
self.widget(QtGui.QCheckBox, "allAxes").setText(
QtGui.QApplication.translate("plot_axes",
"Apply to all axes",
None))
self.widget(QtGui.QLabel, "dimLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Dimensions",
None))
self.widget(QtGui.QLabel, "xPosLabel").setText(
QtGui.QApplication.translate("plot_axes",
"X axis position",
None))
self.widget(QtGui.QLabel, "yPosLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Y axis position",
None))
self.widget(QtGui.QLabel, "scalesLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Scales",
None))
self.widget(QtGui.QCheckBox, "xAuto").setText(
QtGui.QApplication.translate("plot_axes",
"X auto",
None))
self.widget(QtGui.QCheckBox, "yAuto").setText(
QtGui.QApplication.translate("plot_axes",
"Y auto",
None))
self.widget(QtGui.QCheckBox, "allAxes").setText(
QtGui.QApplication.translate("plot_axes",
"Apply to all axes",
None))
self.widget(QtGui.QLabel, "dimLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Dimensions",
None))
self.widget(QtGui.QLabel, "xPosLabel").setText(
QtGui.QApplication.translate("plot_axes",
"X axis position",
None))
self.widget(QtGui.QLabel, "yPosLabel").setText(
QtGui.QApplication.translate("plot_axes",
"Y axis position",
None))
self.widget(QtGui.QSpinBox, "axesIndex").setToolTip(
QtGui.QApplication.translate("plot_axes",
"Index of the active axes",
None))
self.widget(QtGui.QPushButton, "newAxesButton").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Add new axes to the plot",
None))
self.widget(QtGui.QPushButton, "delAxesButton").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Remove selected axes",
None))
self.widget(QtGui.QCheckBox, "allAxes").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Check it to apply transformations to all axes",
None))
self.widget(QtGui.QSlider, "posXMin").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Left bound of axes",
None))
self.widget(QtGui.QSlider, "posXMax").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Right bound of axes",
None))
self.widget(QtGui.QSlider, "posYMin").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Bottom bound of axes",
None))
self.widget(QtGui.QSlider, "posYMax").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Top bound of axes",
None))
self.widget(QtGui.QSpinBox, "xOffset").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Outward offset of X axis",
None))
self.widget(QtGui.QSpinBox, "yOffset").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Outward offset of Y axis",
None))
self.widget(QtGui.QCheckBox, "xAuto").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"X axis scale autoselection",
None))
self.widget(QtGui.QCheckBox, "yAuto").setToolTip(
QtGui.QApplication.translate(
"plot_axes",
"Y axis scale autoselection",
None))
def onAxesId(self, value):
"""Executed when axes index is modified."""
if not self.skip:
self.skip = True
# No active plot case
plt = Plot.getPlot()
if not plt:
self.updateUI()
self.skip = False
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.axId = self.widget(QtGui.QSpinBox, "axesIndex")
form.axId.setMaximum(len(plt.axesList))
if form.axId.value() >= len(plt.axesList):
form.axId.setValue(len(plt.axesList) - 1)
# Send new control to Plot instance
plt.setActiveAxes(form.axId.value())
self.updateUI()
self.skip = False
def onNew(self):
"""Executed when new axes must be created."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.axId = self.widget(QtGui.QSpinBox, "axesIndex")
Plot.addNewAxes()
form.axId.setValue(len(plt.axesList) - 1)
plt.update()
def onRemove(self):
"""Executed when axes must be deleted."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.axId = self.widget(QtGui.QSpinBox, "axesIndex")
# Don't remove first axes
if not form.axId.value():
msg = QtGui.QApplication.translate(
"plot_console",
"Axes 0 can not be deleted",
None)
App.Console.PrintError(msg + "\n")
return
# Remove axes
ax = plt.axes
ax.set_axis_off()
plt.axesList.pop(form.axId.value())
# Ensure that active axes is correct
index = min(form.axId.value(), len(plt.axesList) - 1)
form.axId.setValue(index)
plt.update()
def onDims(self, value):
"""Executed when axes dims have been modified."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xMin = self.widget(QtGui.QSlider, "posXMin")
form.xMax = self.widget(QtGui.QSlider, "posXMax")
form.yMin = self.widget(QtGui.QSlider, "posYMin")
form.yMax = self.widget(QtGui.QSlider, "posYMax")
axesList = [plt.axes]
if form.all.isChecked():
axesList = plt.axesList
# Set new dimensions
xmin = form.xMin.value() / 100.0
xmax = form.xMax.value() / 100.0
ymin = form.yMin.value() / 100.0
ymax = form.yMax.value() / 100.0
for axes in axesList:
axes.set_position([xmin, ymin, xmax - xmin, ymax - ymin])
plt.update()
def onAlign(self, value):
"""Executed when axes align have been modified."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xAlign = self.widget(QtGui.QComboBox, "xAlign")
form.yAlign = self.widget(QtGui.QComboBox, "yAlign")
axesList = [plt.axes]
if form.all.isChecked():
axesList = plt.axesList
# Set new alignment
for axes in axesList:
if form.xAlign.currentIndex() == 0:
axes.xaxis.tick_bottom()
axes.spines['bottom'].set_color((0.0, 0.0, 0.0))
axes.spines['top'].set_color('none')
axes.xaxis.set_ticks_position('bottom')
axes.xaxis.set_label_position('bottom')
else:
axes.xaxis.tick_top()
axes.spines['top'].set_color((0.0, 0.0, 0.0))
axes.spines['bottom'].set_color('none')
axes.xaxis.set_ticks_position('top')
axes.xaxis.set_label_position('top')
if form.yAlign.currentIndex() == 0:
axes.yaxis.tick_left()
axes.spines['left'].set_color((0.0, 0.0, 0.0))
axes.spines['right'].set_color('none')
axes.yaxis.set_ticks_position('left')
axes.yaxis.set_label_position('left')
else:
axes.yaxis.tick_right()
axes.spines['right'].set_color((0.0, 0.0, 0.0))
axes.spines['left'].set_color('none')
axes.yaxis.set_ticks_position('right')
axes.yaxis.set_label_position('right')
plt.update()
def onOffset(self, value):
"""Executed when axes offsets have been modified."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xOffset = self.widget(QtGui.QSpinBox, "xOffset")
form.yOffset = self.widget(QtGui.QSpinBox, "yOffset")
axesList = [plt.axes]
if form.all.isChecked():
axesList = plt.axesList
# Set new offset
for axes in axesList:
# For some reason, modify spines offset erase axes labels, so we
# need store it in order to regenerate later
x = axes.get_xlabel()
y = axes.get_ylabel()
for loc, spine in axes.spines.items():
if loc in ['bottom', 'top']:
spine.set_position(('outward', form.xOffset.value()))
if loc in ['left', 'right']:
spine.set_position(('outward', form.yOffset.value()))
# Now we can restore axes labels
Plot.xlabel(unicode(x))
Plot.ylabel(unicode(y))
plt.update()
def onScales(self):
"""Executed when axes scales have been modified."""
# Ensure that we can work
plt = Plot.getPlot()
if not plt:
self.updateUI()
return
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xAuto = self.widget(QtGui.QCheckBox, "xAuto")
form.yAuto = self.widget(QtGui.QCheckBox, "yAuto")
form.xSMin = self.widget(QtGui.QLineEdit, "xMin")
form.xSMax = self.widget(QtGui.QLineEdit, "xMax")
form.ySMin = self.widget(QtGui.QLineEdit, "yMin")
form.ySMax = self.widget(QtGui.QLineEdit, "yMax")
axesList = [plt.axes]
if form.all.isChecked():
axesList = plt.axesList
if not self.skip:
self.skip = True
# X axis
if form.xAuto.isChecked():
for ax in axesList:
ax.set_autoscalex_on(True)
form.xSMin.setEnabled(False)
form.xSMax.setEnabled(False)
lim = plt.axes.get_xlim()
form.xSMin.setText(str(lim[0]))
form.xSMax.setText(str(lim[1]))
else:
form.xSMin.setEnabled(True)
form.xSMax.setEnabled(True)
try:
xMin = float(form.xSMin.text())
except:
xMin = plt.axes.get_xlim()[0]
form.xSMin.setText(str(xMin))
try:
xMax = float(form.xSMax.text())
except:
xMax = plt.axes.get_xlim()[1]
form.xSMax.setText(str(xMax))
for ax in axesList:
ax.set_xlim((xMin, xMax))
# Y axis
if form.yAuto.isChecked():
for ax in axesList:
ax.set_autoscaley_on(True)
form.ySMin.setEnabled(False)
form.ySMax.setEnabled(False)
lim = plt.axes.get_ylim()
form.ySMin.setText(str(lim[0]))
form.ySMax.setText(str(lim[1]))
else:
form.ySMin.setEnabled(True)
form.ySMax.setEnabled(True)
try:
yMin = float(form.ySMin.text())
except:
yMin = plt.axes.get_ylim()[0]
form.ySMin.setText(str(yMin))
try:
yMax = float(form.ySMax.text())
except:
yMax = plt.axes.get_ylim()[1]
form.ySMax.setText(str(yMax))
for ax in axesList:
ax.set_ylim((yMin, yMax))
plt.update()
self.skip = False
def onMdiArea(self, subWin):
"""Executed when window is selected on mdi area.
Keyword arguments:
subWin -- Selected window.
"""
plt = Plot.getPlot()
if plt != subWin:
self.updateUI()
def updateUI(self):
"""Setup UI controls values if possible"""
plt = Plot.getPlot()
# Get again all the subwidgets (to avoid PySide Pitfalls)
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.axId = self.widget(QtGui.QSpinBox, "axesIndex")
form.new = self.widget(QtGui.QPushButton, "newAxesButton")
form.remove = self.widget(QtGui.QPushButton, "delAxesButton")
form.all = self.widget(QtGui.QCheckBox, "allAxes")
form.xMin = self.widget(QtGui.QSlider, "posXMin")
form.xMax = self.widget(QtGui.QSlider, "posXMax")
form.yMin = self.widget(QtGui.QSlider, "posYMin")
form.yMax = self.widget(QtGui.QSlider, "posYMax")
form.xAlign = self.widget(QtGui.QComboBox, "xAlign")
form.yAlign = self.widget(QtGui.QComboBox, "yAlign")
form.xOffset = self.widget(QtGui.QSpinBox, "xOffset")
form.yOffset = self.widget(QtGui.QSpinBox, "yOffset")
form.xAuto = self.widget(QtGui.QCheckBox, "xAuto")
form.yAuto = self.widget(QtGui.QCheckBox, "yAuto")
form.xSMin = self.widget(QtGui.QLineEdit, "xMin")
form.xSMax = self.widget(QtGui.QLineEdit, "xMax")
form.ySMin = self.widget(QtGui.QLineEdit, "yMin")
form.ySMax = self.widget(QtGui.QLineEdit, "yMax")
# Enable/disable them
form.axId.setEnabled(bool(plt))
form.new.setEnabled(bool(plt))
form.remove.setEnabled(bool(plt))
form.all.setEnabled(bool(plt))
form.xMin.setEnabled(bool(plt))
form.xMax.setEnabled(bool(plt))
form.yMin.setEnabled(bool(plt))
form.yMax.setEnabled(bool(plt))
form.xAlign.setEnabled(bool(plt))
form.yAlign.setEnabled(bool(plt))
form.xOffset.setEnabled(bool(plt))
form.yOffset.setEnabled(bool(plt))
form.xAuto.setEnabled(bool(plt))
form.yAuto.setEnabled(bool(plt))
form.xSMin.setEnabled(bool(plt))
form.xSMax.setEnabled(bool(plt))
form.ySMin.setEnabled(bool(plt))
form.ySMax.setEnabled(bool(plt))
if not plt:
form.axId.setValue(0)
return
# Ensure that active axes is correct
index = min(form.axId.value(), len(plt.axesList) - 1)
form.axId.setValue(index)
# Set dimensions
ax = plt.axes
bb = ax.get_position()
form.xMin.setValue(int(100 * bb._get_xmin()))
form.xMax.setValue(int(100 * bb._get_xmax()))
form.yMin.setValue(int(100 * bb._get_ymin()))
form.yMax.setValue(int(100 * bb._get_ymax()))
# Set alignment and offset
xPos = ax.xaxis.get_ticks_position()
yPos = ax.yaxis.get_ticks_position()
xOffset = ax.spines['bottom'].get_position()[1]
yOffset = ax.spines['left'].get_position()[1]
if xPos == 'bottom' or xPos == 'default':
form.xAlign.setCurrentIndex(0)
else:
form.xAlign.setCurrentIndex(1)
form.xOffset.setValue(xOffset)
if yPos == 'left' or yPos == 'default':
form.yAlign.setCurrentIndex(0)
else:
form.yAlign.setCurrentIndex(1)
form.yOffset.setValue(yOffset)
# Set scales
if ax.get_autoscalex_on():
form.xAuto.setChecked(True)
form.xSMin.setEnabled(False)
form.xSMax.setEnabled(False)
else:
form.xAuto.setChecked(False)
form.xSMin.setEnabled(True)
form.xSMax.setEnabled(True)
lim = ax.get_xlim()
form.xSMin.setText(str(lim[0]))
form.xSMax.setText(str(lim[1]))
if ax.get_autoscaley_on():
form.yAuto.setChecked(True)
form.ySMin.setEnabled(False)
form.ySMax.setEnabled(False)
else:
form.yAuto.setChecked(False)
form.ySMin.setEnabled(True)
form.ySMax.setEnabled(True)
lim = ax.get_ylim()
form.ySMin.setText(str(lim[0]))
form.ySMax.setText(str(lim[1]))
def createTask():
panel = TaskPanel()
Gui.Control.showDialog(panel)
if panel.setupUi():
Gui.Control.closeDialog(panel)
return None
return panel