Merge lp://qastaging/~rick-rickspencer3/desktopcouch/CouchWidget into lp://qastaging/desktopcouch

Proposed by Rick Spencer
Status: Rejected
Rejected by: dobey
Proposed branch: lp://qastaging/~rick-rickspencer3/desktopcouch/CouchWidget
Merge into: lp://qastaging/desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~rick-rickspencer3/desktopcouch/CouchWidget

This proposal supersedes a proposal from 2009-07-23.

To post a comment you must log in.
Revision history for this message
Rick Spencer (rick-rickspencer3) wrote : Posted in a previous version of this proposal

additional widget code to address bug 403032

Revision history for this message
Ken VanDine (ken-vandine) wrote : Posted in a previous version of this proposal

> additional widget code to address bug 403032

If you enter an id that doesn't exist it produces a traceback, you should handle that exception.

Traceback (most recent call last):
  File "desktopcouch/records/couchwidget.py", line 391, in select_ids
    cw.selected_record_ids = entry.get_text().split(",")
  File "desktopcouch/records/couchwidget.py", line 282, in selected_record_ids
    raise IndexError("id %s not found" %id)
IndexError: id asd not found

review: Needs Fixing
Revision history for this message
Rick Spencer (rick-rickspencer3) wrote : Posted in a previous version of this proposal

> > additional widget code to address bug 403032
>
> If you enter an id that doesn't exist it produces a traceback, you should
> handle that exception.
>
> Traceback (most recent call last):
> File "desktopcouch/records/couchwidget.py", line 391, in select_ids
> cw.selected_record_ids = entry.get_text().split(",")
> File "desktopcouch/records/couchwidget.py", line 282, in selected_record_ids
> raise IndexError("id %s not found" %id)
> IndexError: id asd not found

Actually, I throw raise that exception myself. From an API design POV, it seems that it shouldn't let the user try to select ids that don't exist.

review: Needs Resubmitting
Revision history for this message
Rick Spencer (rick-rickspencer3) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
dobey (dobey) wrote : Posted in a previous version of this proposal

> > > additional widget code to address bug 403032
> >
> > If you enter an id that doesn't exist it produces a traceback, you should
> > handle that exception.
> >
> > Traceback (most recent call last):
> > File "desktopcouch/records/couchwidget.py", line 391, in select_ids
> > cw.selected_record_ids = entry.get_text().split(",")
> > File "desktopcouch/records/couchwidget.py", line 282, in
> selected_record_ids
> > raise IndexError("id %s not found" %id)
> > IndexError: id asd not found
>
> Actually, I throw raise that exception myself. From an API design POV, it
> seems that it shouldn't let the user try to select ids that don't exist.

Raising the exception in the API is probably fine. The test app should handle it by showing a "User doesn't exist" error in the UI or something, I guess. The test app should do pretty much the same thing that any app using the API should do. Then in the future we can test the widget using the test app, and LDTP, so check for expected behaviors better, and avoid having the app exit due to an exception, in the middle of testing.

review: Needs Information

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'desktopcouch/records/couchwidget.py'
--- desktopcouch/records/couchwidget.py 2009-07-15 19:05:43 +0000
+++ desktopcouch/records/couchwidget.py 2009-07-23 18:00:29 +0000
@@ -45,6 +45,7 @@
45 self.__record_type = None45 self.__record_type = None
46 self.__headings = None46 self.__headings = None
47 self.__editable = False47 self.__editable = False
48 self.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
4849
49 @property50 @property
50 def headings(self):51 def headings(self):
@@ -210,6 +211,96 @@
210 #add it to the list store211 #add it to the list store
211 self.list_store.append(row)212 self.list_store.append(row)
212213
214 @property
215 def selected_rows(self):
216 """ selected_rows - returns a list of dictionaries
217 for each row selected. Note that the values are not
218 necessarily the complete dictionary for the records, but rather
219 are determined by the headings used for the CouchWidget.
220
221 To get the complete record, use selected_records, or for the record
222 ids, use selected_record_ids
223
224 This property is read only.
225 """
226
227 #get the selected rows in the ListStore
228 selection = self.get_selection()
229 model, model_rows = selection.get_selected_rows()
230
231 rows = [] #list of rows to return
232 for mr in model_rows:
233 row = {} #a row to be added to the list of rows
234 iter = model.get_iter(mr)
235
236 #get the value for each heading and add it to the row
237 for i, h in enumerate(self.headings):
238 row[h] = model.get_value(iter,i)
239
240 #add the row to the list
241 rows.append(row)
242 return rows
243
244 @property
245 def selected_record_ids(self):
246 """ selected_record_ids - a list of document ids that are
247 selected in the CouchWidget. Throws an IndexError if
248 a specified id is not found in the list when setting
249 this property.
250
251 This property is read/write
252
253 """
254
255 #get the selected rows in the ListStore
256 selection = self.get_selection()
257 model, model_rows = selection.get_selected_rows()
258
259 ids = [] # a list of ids to return
260 for mr in model_rows:
261 iter = model.get_iter(mr)
262
263 #add the id to the list
264 id_index = len(self.headings) #id is always last column
265 ids.append(model.get_value(iter,id_index))
266 return ids
267
268
269 @selected_record_ids.setter
270 def selected_record_ids(self, indexes):
271 rows = [] #a list of rows to select
272 for id in indexes:
273 id_found = False #track if the id was found
274
275 for i,r in enumerate(self.list_store):
276 id_index = len(self.headings) #id is always last column
277 if r[id_index] == id: #id matched in ListModel
278 id_found = True #id was good
279 if r not in rows: #don't have duplicates to select
280 rows.append(i)
281 if not id_found: #stop if a requested id was not in the list
282 raise IndexError("id %s not found" %id)
283
284 #select the requested ids
285 selection = self.get_selection()
286 selection.unselect_all()
287 for r in rows:
288 selection.select_path(r)
289
290 @property
291 def selected_records(self):
292 """ selected_records - returns a list of Record objects
293 for those selected in the CouchWidget.
294
295 This property is read only.
296
297 """
298 recs = [] #a list of records to return
299 for id in self.selected_record_ids:
300 #retrieve a record for each id
301 recs.append(Record(record_id = id, record_type = self.record_type))
302 return recs
303
213 def __reset_model(self):304 def __reset_model(self):
214 """ __reset_model - internal funciton, do not call directly.305 """ __reset_model - internal funciton, do not call directly.
215 This function is typically called when properties are set306 This function is typically called when properties are set
@@ -278,6 +369,27 @@
278 else: #it has been saved369 else: #it has been saved
279 self.__db.update_fields(id,{key:new_text})370 self.__db.update_fields(id,{key:new_text})
280371
372def show_selected(widget, widgets):
373 """Test function for selection properties of CouchWidget"""
374 tv, cw = widgets
375 disp = "Rows:\n"
376 for r in cw.selected_rows:
377 disp += str(r) + "\n"
378
379 disp += "\n\n_Ids:\n"
380 for r in cw.selected_record_ids:
381 disp += str(r) + "\n"
382
383 disp += "\n\nRecords:\n"
384 for r in cw.selected_records:
385 disp += str(r) + "\n"
386
387 tv.get_buffer().set_text(disp)
388
389def select_ids(widget, widgets):
390 entry, cw = widgets
391 cw.selected_record_ids = entry.get_text().split(",")
392
281if __name__ == "__main__":393if __name__ == "__main__":
282 """creates a test CouchWidget if called directly"""394 """creates a test CouchWidget if called directly"""
283395
@@ -287,6 +399,11 @@
287 win.connect("destroy",gtk.main_quit)399 win.connect("destroy",gtk.main_quit)
288 win.show()400 win.show()
289401
402 #create a top level container
403 vbox = gtk.VBox(False, False)
404 vbox.show()
405 win.add(vbox)
406
290 #create a test widget with test database values407 #create a test widget with test database values
291 cw = CouchWidget()408 cw = CouchWidget()
292 cw.database = "couch_widget_test"409 cw.database = "couch_widget_test"
@@ -313,6 +430,35 @@
313430
314 #show the control, add it to the window, and run the main loop431 #show the control, add it to the window, and run the main loop
315 cw.show()432 cw.show()
316 win.add(cw)433 vbox.pack_start(cw, False, True)
434
435 #create a test display area
436 hbox = gtk.HBox(False, 5)
437 hbox.show()
438 tv = gtk.TextView()
439 tv.show()
440 cw.connect("cursor-changed",show_selected, (tv,cw))
441
442
443 #create ui for testing selection
444 id_vbox = gtk.VBox(False, 5)
445 id_vbox.show()
446
447 entry = gtk.Entry()
448 entry.show()
449
450 btn = gtk.Button("select ids")
451 btn.show()
452 btn.connect("clicked", select_ids, (entry,cw))
453
454 id_vbox.pack_start(entry, False, False)
455 id_vbox.pack_end(btn, False, False)
456
457 #pack up the window
458 hbox.pack_start(tv, False, False)
459 vbox.pack_end(hbox, False, False)
460 hbox.pack_end(id_vbox, False, False)
461
462 #run the test app
317 gtk.main()463 gtk.main()
318464

Subscribers

People subscribed via source and target branches