CMS 3D CMS Logo

FindDialog.py
Go to the documentation of this file.
1 import logging
2 
3 from PyQt4.QtCore import QCoreApplication,Qt,SIGNAL
4 from PyQt4.QtGui import QDialog,QLabel,QLineEdit,QCheckBox,QPushButton,QVBoxLayout,QHBoxLayout,QMessageBox,QToolButton,QWidget,QLayout
5 
6 from Vispa.Main.Application import Application
7 from Vispa.Share.ThreadChain import ThreadChain
8 
9 class FindDialog(QDialog):
10  def __init__(self,parent=None):
11  logging.debug(__name__ +': __init__')
12  QDialog.__init__(self,parent)
13  self.setWindowFlags(Qt.Window)
14  self.setWindowTitle("Find...")
15 
16  self._findAlgorithm=None
17  self._properties=[]
18  self._scripts=[]
19  self._find=True
20  self._filter=False
21 
22  self.fill()
23 
24  def fill(self):
25  logging.debug(__name__ +': fill')
26  self._findLabelLabel = QLabel("Label: ")
27  self._findLabelLineEdit = QLineEdit()
28  self._findLabelLineEdit.setToolTip("Example: Particle1")
29 
30  self._caseSensitiveCheckBox=QCheckBox("Case sensitive")
31  self._exactMatchCheckBox=QCheckBox("Exact match")
32  self._helpButton = QPushButton("&Help")
33 
34  self._findPreviousButton = QPushButton("&Previous")
35  self._findPreviousButton.hide()
36  self._findNumberLabel = QLabel("?/?")
37  self._findNumberLabel.hide()
38  self._findNextButton = QPushButton("&Find")
39  self._filterButton = QPushButton("&Filter")
40  self._resetButton = QPushButton("&Reset")
41  self._closeButton = QPushButton("&Close")
42 
43  self.setLayout(QVBoxLayout())
44  self.layout().setSizeConstraint(QLayout.SetFixedSize)
45  self._layout1=QHBoxLayout()
46  self._layout3=QHBoxLayout()
47  self._layout4=QHBoxLayout()
48 
49  self._layout1.setSizeConstraint(QLayout.SetDefaultConstraint)
50  self._layout3.setSizeConstraint(QLayout.SetDefaultConstraint)
51  self._layout4.setSizeConstraint(QLayout.SetDefaultConstraint)
52  self.layout().addLayout(self._layout1)
53  self.layout().addLayout(self._layout3)
54  self.layout().addStretch()
55  self.layout().addLayout(self._layout4)
56 
57  self._layout1.addWidget(self._findLabelLabel)
58  self._layout1.addWidget(self._findLabelLineEdit)
59 
60  self._layout3.addWidget(self._helpButton)
61  self._layout3.addStretch()
62  self._layout3.addWidget(self._caseSensitiveCheckBox)
63  self._layout3.addWidget(self._exactMatchCheckBox)
64 
65  self._layout4.addWidget(self._findPreviousButton)
66  self._layout4.addWidget(self._findNumberLabel)
67  self._layout4.addWidget(self._findNextButton)
68  self._layout4.addWidget(self._filterButton)
69  self._layout4.addWidget(self._resetButton)
70  self._layout4.addStretch()
71  self._layout4.addWidget(self._closeButton)
72 
73  self.connect(self._findLabelLineEdit, SIGNAL('textChanged(QString)'), self.edited)
74  self.connect(self._caseSensitiveCheckBox, SIGNAL('stateChanged(int)'), self.edited)
75  self.connect(self._exactMatchCheckBox, SIGNAL('stateChanged(int)'), self.edited)
76 
77  self.connect(self._findPreviousButton, SIGNAL('clicked(bool)'), self.findPrevious)
78  self.connect(self._findNextButton, SIGNAL('clicked(bool)'), self.findNext)
79  self.connect(self._filterButton, SIGNAL('clicked(bool)'), self.filter)
80  self.connect(self._resetButton, SIGNAL('clicked(bool)'), self.reset)
81  self.connect(self._helpButton, SIGNAL('clicked(bool)'), self.help)
82  self.connect(self._closeButton, SIGNAL('clicked(bool)'), self.reject)
83 
84  self._addStringProperty(False,False)
85  self._addScript(False,False)
86 
87  def _removeProperty(self):
88  for property in self._properties:
89  if self.sender() in property:
90  self._remove(property)
91  return
92 
93  def _remove(self,object):
94  for o in object:
95  if isinstance(o,QWidget):
96  o.close()
97  self.layout().removeItem(object[0])
98  if object in self._properties:
99  self._properties.remove(object)
100  elif object in self._scripts:
101  self._scripts.remove(object)
102 
103  def _addStringProperty(self,bool,deletable=True):
104 
105  layout2=QHBoxLayout()
106 
107  findPropertyNameLabel = QLabel("Property: ")
108  findPropertyNameLineEdit = QLineEdit()
109  findPropertyNameLineEdit.setToolTip("Example: Label = Particle1 ")
110  findPropertyValueLabel = QLabel(" = ")
111  findPropertyValueLineEdit = QLineEdit()
112  findPropertyValueLineEdit.setToolTip("Example: Label = Particle1 ")
113  propertyAdd = QToolButton()
114  propertyAdd.setText("+")
115  propertyDelete = QToolButton()
116  propertyDelete.setText("-")
117 
118  if deletable:
119  propertyAdd.hide()
120  else:
121  propertyDelete.hide()
122  layout2.addWidget(propertyAdd)
123  layout2.addWidget(propertyDelete)
124  layout2.addWidget(findPropertyNameLabel)
125  layout2.addWidget(findPropertyNameLineEdit)
126  layout2.addWidget(findPropertyValueLabel)
127  layout2.addWidget(findPropertyValueLineEdit)
128 
129  self.connect(findPropertyNameLineEdit, SIGNAL('textChanged(QString)'), self.edited)
130  self.connect(findPropertyValueLineEdit, SIGNAL('textChanged(QString)'), self.edited)
131  self.connect(propertyAdd, SIGNAL('clicked(bool)'), self._addStringProperty)
132  self.connect(propertyDelete, SIGNAL('clicked(bool)'), self._removeProperty)
133 
134  self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
135 
136  self._properties+=[(layout2,findPropertyNameLineEdit,findPropertyValueLineEdit,findPropertyNameLabel,findPropertyValueLabel,propertyAdd,propertyDelete)]
137 
138  def _removeScript(self):
139  for script in self._scripts:
140  if self.sender() in script:
141  self._remove(script)
142  return
143 
144  def _addScript(self,bool,deletable=True):
145 
146  layout2=QHBoxLayout()
147 
148  findScriptLabel = QLabel("Filter = ")
149  findScriptLineEdit = QLineEdit("")
150  findScriptLineEdit.setToolTip("Example: object.Label == 'Particle1' ")
151  scriptAdd = QToolButton()
152  scriptAdd.setText("+")
153  scriptDelete = QToolButton()
154  scriptDelete.setText("-")
155 
156  if deletable:
157  scriptAdd.hide()
158  else:
159  scriptDelete.hide()
160  layout2.addWidget(scriptAdd)
161  layout2.addWidget(scriptDelete)
162  layout2.addWidget(findScriptLabel)
163  layout2.addWidget(findScriptLineEdit)
164 
165  self.connect(findScriptLineEdit, SIGNAL('textChanged(QString)'), self.edited)
166  self.connect(scriptAdd, SIGNAL('clicked(bool)'), self._addScript)
167  self.connect(scriptDelete, SIGNAL('clicked(bool)'), self._removeScript)
168 
169  self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
170 
171  self._scripts+=[(layout2,findScriptLineEdit,findScriptLabel,scriptAdd,scriptDelete)]
172 
173  def onScreen(self, filter=False, find=True):
174  logging.debug(__name__ +': onScreen')
175  self._find=find
176  self._filter=filter
177  if self._find and self._filter:
178  self._findNextButton.setDefault(True)
179  self.setWindowTitle("Find/Filter...")
180  elif self._find:
181  self._findNextButton.setDefault(True)
182  self.setWindowTitle("Find...")
183  elif self._filter:
184  self._filterButton.setDefault(True)
185  self.setWindowTitle("Filter...")
186 
187  self._findNextButton.setVisible(find)
188  if not find:
189  self._findPreviousButton.setVisible(find)
190  self._filterButton.setVisible(filter)
191  self.show()
192  self.raise_()
193  self.activateWindow()
194  self._findLabelLineEdit.setFocus()
195 
196  def keyPressEvent(self, event):
197  """
198  """
199  if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_W:
200  self.close()
201  QDialog.keyPressEvent(self, event)
202 
203  def setFindAlgorithm(self,findAlgorithm):
204  logging.debug(__name__ +': setFindAlgorithm')
205  self._findAlgorithm=findAlgorithm
206 
207  def findAlgorithm(self):
208  return self._findAlgorithm
209 
210  def label(self):
211  return str(self._findLabelLineEdit.text().toAscii())
212 
213  def setLabel(self,label):
214  logging.debug(__name__ +': setLabel '+label)
215  self._findLabelLineEdit.setText(label)
216 
217  def properties(self):
218  return [(str(property[1].text().toAscii()),str(property[2].text().toAscii())) for property in self._properties]
219 
220  def scripts(self):
221  return [str(script[1].text().toAscii()) for script in self._scripts]
222 
223  def caseSensitive(self):
224  return self._caseSensitiveCheckBox.checkState()==Qt.Checked
225 
226  def exactMatch(self):
227  return self._exactMatchCheckBox.checkState()==Qt.Checked
228 
229  def edited(self):
230  self._findPreviousButton.hide()
231  if self._findNextButton.isVisible():
232  self._findNumberLabel.hide()
233  self._findNextButton.setText("&Find")
234 
236  current=self._findAlgorithm.currentNumber()
237  total=self._findAlgorithm.numberOfResults()
238  message=self._findAlgorithm.message()
239  text=""
240  if self._filter:
241  text=str(total)+" found"
242  else:
243  if total>0:
244  text=str(current)+"/"+str(total)
245  else:
246  text="not found"
247  if message:
248  text+=" ("+message+")"
249  self._findNumberLabel.setText(text)
250 
251  def findPrevious(self):
252  logging.debug(__name__ +': findPrevious')
253  object=self._findAlgorithm.previous()
254  self._updateNumberLabel()
255  self.emit(SIGNAL("found"),object)
256 
257  def findNext(self):
258  logging.debug(__name__ +': findNext')
259  if not self._findPreviousButton.isVisible():
260  self._findNextButton.setVisible(False)
261  self._filterButton.setVisible(False)
262  self._resetButton.setVisible(False)
263  self._findNumberLabel.setText("Searching...")
264  self._findNumberLabel.show()
265  thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self)
266  while thread.isRunning():
267  if not Application.NO_PROCESS_EVENTS:
268  QCoreApplication.instance().processEvents()
269  object=thread.returnValue()
270  self._findNextButton.setVisible(True)
271  if self._filter:
272  self._filterButton.setVisible(True)
273  self._resetButton.setVisible(True)
274  self._findPreviousButton.show()
275  self._findNextButton.setText("&Next")
276  else:
277  object=next(self._findAlgorithm)
278  self._updateNumberLabel()
279  self.emit(SIGNAL("found"),object)
280 
281  def filter(self):
282  logging.debug(__name__ +': filter')
283  self._findNextButton.setVisible(False)
284  self._filterButton.setVisible(False)
285  self._resetButton.setVisible(False)
286  self._findNumberLabel.setText("Searching...")
287  self._findNumberLabel.show()
288  thread = ThreadChain(self._findAlgorithm.findUsingFindDialog, self)
289  while thread.isRunning():
290  if not Application.NO_PROCESS_EVENTS:
291  QCoreApplication.instance().processEvents()
292  if self._find:
293  self._findNextButton.setVisible(True)
294  self._filterButton.setVisible(True)
295  self._resetButton.setVisible(True)
296  self._updateNumberLabel()
297  self.emit(SIGNAL("filtered"),self._findAlgorithm.results())
298 
299  def reset(self):
300  self.setLabel("")
301  for o in self._scripts+self._properties:
302  self._remove(o)
303  self._addStringProperty(False,False)
304  self._addScript(False,False)
305  self._findAlgorithm.clear()
306  self._updateNumberLabel()
307  if self._filter:
308  self.emit(SIGNAL("filtered"),None)
309  self.update()
310 
311  def help(self):
312  QMessageBox.about(self, 'Info', "You can find objects \n1. using their label shown in the center view, \n2. their properties shown in the property view, or \n3. using a Python script returning a boolean. Empty fields are ignored. Examples are shown as tool tips.")
def _remove(self, object)
Definition: FindDialog.py:93
def onScreen(self, filter=False, find=True)
Definition: FindDialog.py:173
def _addStringProperty(self, bool, deletable=True)
Definition: FindDialog.py:103
def __init__(self, parent=None)
Definition: FindDialog.py:10
def keyPressEvent(self, event)
Definition: FindDialog.py:196
def _addScript(self, bool, deletable=True)
Definition: FindDialog.py:144
def setFindAlgorithm(self, findAlgorithm)
Definition: FindDialog.py:203