#*************************************************************************** #* * #* Copyright (c) 2011, 2012 * #* Jose Luis Cercos Pita * #* * #* 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.qApp.topLevelWidgets() for i in toplevel: if i.metaObject().className() == "Gui::MainWindow": return i raise Exception("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, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "axesLabel").setText( QtGui.QApplication.translate("plot_axes", "Active axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "allAxes").setText( QtGui.QApplication.translate("plot_axes", "Apply to all axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "dimLabel").setText( QtGui.QApplication.translate("plot_axes", "Dimensions", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "xPosLabel").setText( QtGui.QApplication.translate("plot_axes", "X axis position", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "yPosLabel").setText( QtGui.QApplication.translate("plot_axes", "Y axis position", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "scalesLabel").setText( QtGui.QApplication.translate("plot_axes", "Scales", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "xAuto").setText( QtGui.QApplication.translate("plot_axes", "X auto", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "yAuto").setText( QtGui.QApplication.translate("plot_axes", "Y auto", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "allAxes").setText( QtGui.QApplication.translate("plot_axes", "Apply to all axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "dimLabel").setText( QtGui.QApplication.translate("plot_axes", "Dimensions", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "xPosLabel").setText( QtGui.QApplication.translate("plot_axes", "X axis position", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QLabel, "yPosLabel").setText( QtGui.QApplication.translate("plot_axes", "Y axis position", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSpinBox, "axesIndex").setToolTip( QtGui.QApplication.translate("plot_axes", "Index of the active axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QPushButton, "newAxesButton").setToolTip( QtGui.QApplication.translate( "plot_axes", "Add new axes to the plot", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QPushButton, "delAxesButton").setToolTip( QtGui.QApplication.translate( "plot_axes", "Remove selected axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "allAxes").setToolTip( QtGui.QApplication.translate( "plot_axes", "Check it to apply transformations to all axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSlider, "posXMin").setToolTip( QtGui.QApplication.translate( "plot_axes", "Left bound of axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSlider, "posXMax").setToolTip( QtGui.QApplication.translate( "plot_axes", "Right bound of axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSlider, "posYMin").setToolTip( QtGui.QApplication.translate( "plot_axes", "Bottom bound of axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSlider, "posYMax").setToolTip( QtGui.QApplication.translate( "plot_axes", "Top bound of axes", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSpinBox, "xOffset").setToolTip( QtGui.QApplication.translate( "plot_axes", "Outward offset of X axis", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QSpinBox, "yOffset").setToolTip( QtGui.QApplication.translate( "plot_axes", "Outward offset of Y axis", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "xAuto").setToolTip( QtGui.QApplication.translate( "plot_axes", "X axis scale autoselection", None, QtGui.QApplication.UnicodeUTF8)) self.widget(QtGui.QCheckBox, "yAuto").setToolTip( QtGui.QApplication.translate( "plot_axes", "Y axis scale autoselection", None, QtGui.QApplication.UnicodeUTF8)) 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 taht 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, QtGui.QApplication.UnicodeUTF8) 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 alignement 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.iteritems(): 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