Merge lp:~francesco-marella/pasaffe/clone_context-menu into lp:~mdeslaur/pasaffe/trunk
- clone_context-menu
- Merge into trunk
Proposed by
Francesco Marella
Status: | Merged |
---|---|
Merged at revision: | 165 |
Proposed branch: | lp:~francesco-marella/pasaffe/clone_context-menu |
Merge into: | lp:~mdeslaur/pasaffe/trunk |
Diff against target: |
318 lines (+188/-54) 2 files modified
data/ui/PasaffeWindow.ui (+124/-43) pasaffe/PasaffeWindow.py (+64/-11) |
To merge this branch: | bzr merge lp:~francesco-marella/pasaffe/clone_context-menu |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marc Deslauriers | Approve | ||
Review via email: mp+77385@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/ui/PasaffeWindow.ui' |
2 | --- data/ui/PasaffeWindow.ui 2011-08-22 21:11:16 +0000 |
3 | +++ data/ui/PasaffeWindow.ui 2011-09-28 18:38:22 +0000 |
4 | @@ -9,6 +9,26 @@ |
5 | <property name="can_focus">False</property> |
6 | <property name="stock">gtk-copy</property> |
7 | </object> |
8 | + <object class="GtkImage" id="image10"> |
9 | + <property name="visible">True</property> |
10 | + <property name="can_focus">False</property> |
11 | + <property name="stock">gnome-stock-text-indent</property> |
12 | + </object> |
13 | + <object class="GtkImage" id="image11"> |
14 | + <property name="visible">True</property> |
15 | + <property name="can_focus">False</property> |
16 | + <property name="stock">gtk-copy</property> |
17 | + </object> |
18 | + <object class="GtkImage" id="image12"> |
19 | + <property name="visible">True</property> |
20 | + <property name="can_focus">False</property> |
21 | + <property name="stock">gtk-copy</property> |
22 | + </object> |
23 | + <object class="GtkImage" id="image13"> |
24 | + <property name="visible">True</property> |
25 | + <property name="can_focus">False</property> |
26 | + <property name="stock">gtk-copy</property> |
27 | + </object> |
28 | <object class="GtkImage" id="image2"> |
29 | <property name="visible">True</property> |
30 | <property name="can_focus">False</property> |
31 | @@ -49,6 +69,11 @@ |
32 | <property name="stock">gtk-info</property> |
33 | <property name="icon-size">1</property> |
34 | </object> |
35 | + <object class="GtkImage" id="image9"> |
36 | + <property name="visible">True</property> |
37 | + <property name="can_focus">False</property> |
38 | + <property name="stock">gtk-copy</property> |
39 | + </object> |
40 | <object class="GtkListStore" id="liststore1"> |
41 | <columns> |
42 | <!-- column-name entry_name --> |
43 | @@ -57,6 +82,93 @@ |
44 | <column type="gchararray"/> |
45 | </columns> |
46 | </object> |
47 | + <object class="GtkMenu" id="menu_popup"> |
48 | + <property name="visible">True</property> |
49 | + <property name="can_focus">False</property> |
50 | + <child> |
51 | + <object class="GtkImageMenuItem" id="mnu_add1"> |
52 | + <property name="label">gtk-add</property> |
53 | + <property name="visible">True</property> |
54 | + <property name="can_focus">False</property> |
55 | + <property name="use_action_appearance">False</property> |
56 | + <property name="use_underline">True</property> |
57 | + <property name="use_stock">True</property> |
58 | + <signal name="activate" handler="on_mnu_add_activate" swapped="no"/> |
59 | + </object> |
60 | + </child> |
61 | + <child> |
62 | + <object class="GtkImageMenuItem" id="mnu_edit1"> |
63 | + <property name="label">gtk-edit</property> |
64 | + <property name="visible">True</property> |
65 | + <property name="can_focus">False</property> |
66 | + <property name="use_action_appearance">False</property> |
67 | + <property name="use_underline">True</property> |
68 | + <property name="use_stock">True</property> |
69 | + <signal name="activate" handler="on_mnu_edit1_activate" swapped="no"/> |
70 | + </object> |
71 | + </child> |
72 | + <child> |
73 | + <object class="GtkImageMenuItem" id="mnu_clone1"> |
74 | + <property name="label" translatable="yes">Clone</property> |
75 | + <property name="visible">True</property> |
76 | + <property name="can_focus">False</property> |
77 | + <property name="use_action_appearance">False</property> |
78 | + <property name="image">image13</property> |
79 | + <property name="use_stock">False</property> |
80 | + <signal name="activate" handler="on_mnu_clone_activate" swapped="no"/> |
81 | + </object> |
82 | + </child> |
83 | + <child> |
84 | + <object class="GtkImageMenuItem" id="mnu_delete1"> |
85 | + <property name="label">gtk-delete</property> |
86 | + <property name="visible">True</property> |
87 | + <property name="can_focus">False</property> |
88 | + <property name="use_action_appearance">False</property> |
89 | + <property name="use_underline">True</property> |
90 | + <property name="use_stock">True</property> |
91 | + <signal name="activate" handler="on_mnu_delete_activate" swapped="no"/> |
92 | + </object> |
93 | + </child> |
94 | + <child> |
95 | + <object class="GtkSeparatorMenuItem" id="separatormenuitem3"> |
96 | + <property name="visible">True</property> |
97 | + <property name="can_focus">False</property> |
98 | + </object> |
99 | + </child> |
100 | + <child> |
101 | + <object class="GtkImageMenuItem" id="url_copy1"> |
102 | + <property name="label" translatable="yes">Copy URL</property> |
103 | + <property name="visible">True</property> |
104 | + <property name="can_focus">False</property> |
105 | + <property name="use_action_appearance">False</property> |
106 | + <property name="image">image12</property> |
107 | + <property name="use_stock">False</property> |
108 | + <signal name="activate" handler="on_url_copy_activate" swapped="no"/> |
109 | + </object> |
110 | + </child> |
111 | + <child> |
112 | + <object class="GtkImageMenuItem" id="username_copy1"> |
113 | + <property name="label" translatable="yes">Copy Username</property> |
114 | + <property name="visible">True</property> |
115 | + <property name="can_focus">False</property> |
116 | + <property name="use_action_appearance">False</property> |
117 | + <property name="image">image11</property> |
118 | + <property name="use_stock">False</property> |
119 | + <signal name="activate" handler="on_username_copy_activate" swapped="no"/> |
120 | + </object> |
121 | + </child> |
122 | + <child> |
123 | + <object class="GtkImageMenuItem" id="password_copy1"> |
124 | + <property name="label" translatable="yes">Copy Password</property> |
125 | + <property name="visible">True</property> |
126 | + <property name="can_focus">False</property> |
127 | + <property name="use_action_appearance">False</property> |
128 | + <property name="image">image10</property> |
129 | + <property name="use_stock">False</property> |
130 | + <signal name="activate" handler="on_password_copy_activate" swapped="no"/> |
131 | + </object> |
132 | + </child> |
133 | + </object> |
134 | <object class="PasaffeWindow" id="pasaffe_window"> |
135 | <property name="can_focus">False</property> |
136 | <property name="title" translatable="yes">Pasaffe</property> |
137 | @@ -166,49 +278,6 @@ |
138 | <property name="visible">True</property> |
139 | <property name="can_focus">False</property> |
140 | <child> |
141 | - <object class="GtkImageMenuItem" id="mnu_cut"> |
142 | - <property name="label">gtk-cut</property> |
143 | - <property name="sensitive">False</property> |
144 | - <property name="can_focus">False</property> |
145 | - <property name="use_action_appearance">False</property> |
146 | - <property name="use_underline">True</property> |
147 | - <property name="use_stock">True</property> |
148 | - <accelerator key="x" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
149 | - <signal name="activate" handler="on_mnu_cut_activate" swapped="no"/> |
150 | - </object> |
151 | - </child> |
152 | - <child> |
153 | - <object class="GtkImageMenuItem" id="mnu_copy"> |
154 | - <property name="label">gtk-copy</property> |
155 | - <property name="visible">True</property> |
156 | - <property name="can_focus">False</property> |
157 | - <property name="use_action_appearance">False</property> |
158 | - <property name="use_underline">True</property> |
159 | - <property name="use_stock">True</property> |
160 | - <accelerator key="c" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
161 | - <signal name="activate" handler="on_mnu_copy_activate" swapped="no"/> |
162 | - </object> |
163 | - </child> |
164 | - <child> |
165 | - <object class="GtkImageMenuItem" id="mnu_paste"> |
166 | - <property name="label">gtk-paste</property> |
167 | - <property name="sensitive">False</property> |
168 | - <property name="can_focus">False</property> |
169 | - <property name="use_action_appearance">False</property> |
170 | - <property name="use_underline">True</property> |
171 | - <property name="use_stock">True</property> |
172 | - <accelerator key="v" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
173 | - <signal name="activate" handler="on_mnu_paste_activate" swapped="no"/> |
174 | - </object> |
175 | - </child> |
176 | - <child> |
177 | - <object class="GtkSeparatorMenuItem" id="separatormenuitem3"> |
178 | - <property name="visible">True</property> |
179 | - <property name="can_focus">False</property> |
180 | - <property name="use_action_appearance">False</property> |
181 | - </object> |
182 | - </child> |
183 | - <child> |
184 | <object class="GtkImageMenuItem" id="mnu_add"> |
185 | <property name="label">gtk-add</property> |
186 | <property name="visible">True</property> |
187 | @@ -220,6 +289,17 @@ |
188 | </object> |
189 | </child> |
190 | <child> |
191 | + <object class="GtkImageMenuItem" id="mnu_clone"> |
192 | + <property name="label">Clone</property> |
193 | + <property name="visible">True</property> |
194 | + <property name="can_focus">False</property> |
195 | + <property name="use_action_appearance">False</property> |
196 | + <property name="image">image9</property> |
197 | + <property name="use_stock">False</property> |
198 | + <signal name="activate" handler="on_mnu_clone_activate" swapped="no"/> |
199 | + </object> |
200 | + </child> |
201 | + <child> |
202 | <object class="GtkImageMenuItem" id="mnu_delete"> |
203 | <property name="label">gtk-delete</property> |
204 | <property name="visible">True</property> |
205 | @@ -581,6 +661,7 @@ |
206 | <property name="model">liststore1</property> |
207 | <property name="headers_visible">False</property> |
208 | <signal name="cursor-changed" handler="on_treeview1_cursor_changed" swapped="no"/> |
209 | + <signal name="button-press-event" handler="on_treeview1_button_press_event" swapped="no"/> |
210 | <signal name="row-activated" handler="on_treeview1_row_activated" swapped="no"/> |
211 | <child> |
212 | <object class="GtkTreeViewColumn" id="treeviewcolumn1"> |
213 | |
214 | === modified file 'pasaffe/PasaffeWindow.py' |
215 | --- pasaffe/PasaffeWindow.py 2011-09-27 06:58:19 +0000 |
216 | +++ pasaffe/PasaffeWindow.py 2011-09-28 18:38:22 +0000 |
217 | @@ -240,6 +240,18 @@ |
218 | self.ui.display_secrets.set_active(False) |
219 | self.ui.mnu_display_secrets.set_active(False) |
220 | |
221 | + def on_treeview1_button_press_event(self, treeview, event): |
222 | + if event.button == 3: |
223 | + x = int(event.x) |
224 | + y = int(event.y) |
225 | + time = event.time |
226 | + pthinfo = treeview.get_path_at_pos(x, y) |
227 | + if pthinfo is not None: |
228 | + path, col, cellx, celly = pthinfo |
229 | + treeview.grab_focus() |
230 | + treeview.set_cursor(path, col, 0) |
231 | + self.ui.menu_popup.popup(None, None, None, 3, time) |
232 | + |
233 | def add_entry(self): |
234 | self.disable_idle_timeout() |
235 | |
236 | @@ -272,6 +284,47 @@ |
237 | self.save_db() |
238 | self.set_idle_timeout() |
239 | |
240 | + def clone_entry(self, entry_uuid): |
241 | + record_list = ( 3, 4, 5, 6, 13 ) |
242 | + self.disable_idle_timeout() |
243 | + |
244 | + # Make sure dialog isn't already open |
245 | + if self.editdetails_dialog is not None: |
246 | + self.editdetails_dialog.present() |
247 | + return |
248 | + |
249 | + uuid = os.urandom(16) |
250 | + uuid_hex = uuid.encode("hex") |
251 | + timestamp = struct.pack("<I", int(time.time())) |
252 | + new_entry = {1: uuid, 3: '', 4: '', 5: '', 6: '', |
253 | + 7: timestamp, 8: timestamp, 12: timestamp, 13: ''} |
254 | + |
255 | + for record in self.passfile.records: |
256 | + if record[1] == entry_uuid.decode("hex"): |
257 | + for record_type in record_list: |
258 | + if record.has_key(record_type): |
259 | + new_entry[record_type] = record[record_type] |
260 | + break |
261 | + |
262 | + self.passfile.records.append(new_entry) |
263 | + |
264 | + response = self.edit_entry(uuid_hex) |
265 | + if response != gtk.RESPONSE_OK: |
266 | + self.delete_entry(uuid_hex) |
267 | + else: |
268 | + self.display_entries() |
269 | + item = self.ui.treeview1.get_model().get_iter_first() |
270 | + while (item != None): |
271 | + if self.ui.liststore1.get_value(item, 1) == uuid_hex: |
272 | + self.ui.treeview1.get_selection().select_iter(item) |
273 | + self.display_data(uuid_hex) |
274 | + break |
275 | + else: |
276 | + item = self.ui.treeview1.get_model().iter_next(item) |
277 | + if preferences['auto-save'] == True: |
278 | + self.save_db() |
279 | + self.set_idle_timeout() |
280 | + |
281 | def remove_entry(self): |
282 | treemodel, treeiter = self.ui.treeview1.get_selection().get_selected() |
283 | if treeiter != None: |
284 | @@ -423,17 +476,11 @@ |
285 | else: |
286 | self.set_idle_timeout() |
287 | |
288 | - def on_mnu_cut_activate(self, menuitem): |
289 | - print "TODO: implement on_mnu_cut_activate()" |
290 | - |
291 | - def on_mnu_copy_activate(self, menuitem): |
292 | - self.set_idle_timeout() |
293 | - clipboard = gtk.clipboard_get() |
294 | - self.ui.textview1.get_buffer().copy_clipboard(clipboard) |
295 | - clipboard.store() |
296 | - |
297 | - def on_mnu_paste_activate(self, menuitem): |
298 | - print "TODO: implement on_mnu_paste_activate()" |
299 | + def on_mnu_clone_activate(self, menuitem): |
300 | + treemodel, treeiter = self.ui.treeview1.get_selection().get_selected() |
301 | + if treeiter != None: |
302 | + entry_uuid = treemodel.get_value(treeiter, 1) |
303 | + self.clone_entry(entry_uuid) |
304 | |
305 | def on_username_copy_activate(self, menuitem): |
306 | self.copy_selected_entry_item(4) |
307 | @@ -483,6 +530,12 @@ |
308 | def on_mnu_add_activate(self, menuitem): |
309 | self.add_entry() |
310 | |
311 | + def on_mnu_edit1_activate(self, menuitem): |
312 | + treemodel, treeiter = self.ui.treeview1.get_selection().get_selected() |
313 | + if treeiter != None: |
314 | + entry_uuid = treemodel.get_value(treeiter, 1) |
315 | + self.edit_entry(entry_uuid) |
316 | + |
317 | def on_mnu_delete_activate(self, menuitem): |
318 | self.remove_entry() |
319 |
Looks good, thanks!