Merge lp:~francesco-marella/pasaffe/clone_context-menu into lp:~mdeslaur/pasaffe/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
Reviewer Review Type Date Requested Status
Marc Deslauriers Approve
Review via email: mp+77385@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Looks good, thanks!

review: Approve

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

Subscribers

People subscribed via source and target branches