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
1=== modified file 'desktopcouch/records/couchwidget.py'
2--- desktopcouch/records/couchwidget.py 2009-07-15 19:05:43 +0000
3+++ desktopcouch/records/couchwidget.py 2009-07-23 18:00:29 +0000
4@@ -45,6 +45,7 @@
5 self.__record_type = None
6 self.__headings = None
7 self.__editable = False
8+ self.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
9
10 @property
11 def headings(self):
12@@ -210,6 +211,96 @@
13 #add it to the list store
14 self.list_store.append(row)
15
16+ @property
17+ def selected_rows(self):
18+ """ selected_rows - returns a list of dictionaries
19+ for each row selected. Note that the values are not
20+ necessarily the complete dictionary for the records, but rather
21+ are determined by the headings used for the CouchWidget.
22+
23+ To get the complete record, use selected_records, or for the record
24+ ids, use selected_record_ids
25+
26+ This property is read only.
27+ """
28+
29+ #get the selected rows in the ListStore
30+ selection = self.get_selection()
31+ model, model_rows = selection.get_selected_rows()
32+
33+ rows = [] #list of rows to return
34+ for mr in model_rows:
35+ row = {} #a row to be added to the list of rows
36+ iter = model.get_iter(mr)
37+
38+ #get the value for each heading and add it to the row
39+ for i, h in enumerate(self.headings):
40+ row[h] = model.get_value(iter,i)
41+
42+ #add the row to the list
43+ rows.append(row)
44+ return rows
45+
46+ @property
47+ def selected_record_ids(self):
48+ """ selected_record_ids - a list of document ids that are
49+ selected in the CouchWidget. Throws an IndexError if
50+ a specified id is not found in the list when setting
51+ this property.
52+
53+ This property is read/write
54+
55+ """
56+
57+ #get the selected rows in the ListStore
58+ selection = self.get_selection()
59+ model, model_rows = selection.get_selected_rows()
60+
61+ ids = [] # a list of ids to return
62+ for mr in model_rows:
63+ iter = model.get_iter(mr)
64+
65+ #add the id to the list
66+ id_index = len(self.headings) #id is always last column
67+ ids.append(model.get_value(iter,id_index))
68+ return ids
69+
70+
71+ @selected_record_ids.setter
72+ def selected_record_ids(self, indexes):
73+ rows = [] #a list of rows to select
74+ for id in indexes:
75+ id_found = False #track if the id was found
76+
77+ for i,r in enumerate(self.list_store):
78+ id_index = len(self.headings) #id is always last column
79+ if r[id_index] == id: #id matched in ListModel
80+ id_found = True #id was good
81+ if r not in rows: #don't have duplicates to select
82+ rows.append(i)
83+ if not id_found: #stop if a requested id was not in the list
84+ raise IndexError("id %s not found" %id)
85+
86+ #select the requested ids
87+ selection = self.get_selection()
88+ selection.unselect_all()
89+ for r in rows:
90+ selection.select_path(r)
91+
92+ @property
93+ def selected_records(self):
94+ """ selected_records - returns a list of Record objects
95+ for those selected in the CouchWidget.
96+
97+ This property is read only.
98+
99+ """
100+ recs = [] #a list of records to return
101+ for id in self.selected_record_ids:
102+ #retrieve a record for each id
103+ recs.append(Record(record_id = id, record_type = self.record_type))
104+ return recs
105+
106 def __reset_model(self):
107 """ __reset_model - internal funciton, do not call directly.
108 This function is typically called when properties are set
109@@ -278,6 +369,27 @@
110 else: #it has been saved
111 self.__db.update_fields(id,{key:new_text})
112
113+def show_selected(widget, widgets):
114+ """Test function for selection properties of CouchWidget"""
115+ tv, cw = widgets
116+ disp = "Rows:\n"
117+ for r in cw.selected_rows:
118+ disp += str(r) + "\n"
119+
120+ disp += "\n\n_Ids:\n"
121+ for r in cw.selected_record_ids:
122+ disp += str(r) + "\n"
123+
124+ disp += "\n\nRecords:\n"
125+ for r in cw.selected_records:
126+ disp += str(r) + "\n"
127+
128+ tv.get_buffer().set_text(disp)
129+
130+def select_ids(widget, widgets):
131+ entry, cw = widgets
132+ cw.selected_record_ids = entry.get_text().split(",")
133+
134 if __name__ == "__main__":
135 """creates a test CouchWidget if called directly"""
136
137@@ -287,6 +399,11 @@
138 win.connect("destroy",gtk.main_quit)
139 win.show()
140
141+ #create a top level container
142+ vbox = gtk.VBox(False, False)
143+ vbox.show()
144+ win.add(vbox)
145+
146 #create a test widget with test database values
147 cw = CouchWidget()
148 cw.database = "couch_widget_test"
149@@ -313,6 +430,35 @@
150
151 #show the control, add it to the window, and run the main loop
152 cw.show()
153- win.add(cw)
154+ vbox.pack_start(cw, False, True)
155+
156+ #create a test display area
157+ hbox = gtk.HBox(False, 5)
158+ hbox.show()
159+ tv = gtk.TextView()
160+ tv.show()
161+ cw.connect("cursor-changed",show_selected, (tv,cw))
162+
163+
164+ #create ui for testing selection
165+ id_vbox = gtk.VBox(False, 5)
166+ id_vbox.show()
167+
168+ entry = gtk.Entry()
169+ entry.show()
170+
171+ btn = gtk.Button("select ids")
172+ btn.show()
173+ btn.connect("clicked", select_ids, (entry,cw))
174+
175+ id_vbox.pack_start(entry, False, False)
176+ id_vbox.pack_end(btn, False, False)
177+
178+ #pack up the window
179+ hbox.pack_start(tv, False, False)
180+ vbox.pack_end(hbox, False, False)
181+ hbox.pack_end(id_vbox, False, False)
182+
183+ #run the test app
184 gtk.main()
185

Subscribers

People subscribed via source and target branches