~olive-team/olive/trunk

190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
1
# Copyright (C) 2007 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
2
# Copyright (C) 2007 by Jelmer Vernooij <jelmer@samba.org>
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
try:
19
    import pygtk
20
    pygtk.require("2.0")
21
except:
22
    pass
23
24
import gtk
25
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
26
from bzrlib.plugins.gtk import _i18n
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
27
from bzrlib.plugins.gtk.revisionview import RevisionView
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
28
from bzrlib.plugins.gtk.window import Window
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
29
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
30
from dialog import error_dialog
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
31
from revidbox import RevisionSelectionBox
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
32
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
33
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
34
class TagsWindow(Window):
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
35
    """ Tags window. Allows the user to view/add/remove tags. """
36
    def __init__(self, branch, parent=None):
37
        """ Initialize the Tags window. """
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
38
        Window.__init__(self, parent)
275.1.3 by Daniel Schierbeck
Close tags window when 'destroy' signal is received.
39
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
40
        # Get arguments
41
        self.branch = branch
275.1.5 by Daniel Schierbeck
Made windows close correctly on Ctrl-W and made the application quit on Ctrl-Q.
42
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
43
        # Create the widgets
44
        self._button_add = gtk.Button(stock=gtk.STOCK_ADD)
45
        self._button_remove = gtk.Button(stock=gtk.STOCK_REMOVE)
190.1.4 by Szilveszter Farkas (Phanatic)
Added Refresh button to the Tags window.
46
        self._button_refresh = gtk.Button(stock=gtk.STOCK_REFRESH)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
47
        self._button_close = gtk.Button(stock=gtk.STOCK_CLOSE)
48
        self._model = gtk.ListStore(str, str)
49
        self._treeview_tags = gtk.TreeView(self._model)
50
        self._scrolledwindow_tags = gtk.ScrolledWindow()
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
51
        self._revisionview = RevisionView()
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
52
        self._hbox = gtk.HBox()
53
        self._vbox_buttons = gtk.VBox()
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
54
        self._vbox_buttons_top = gtk.VBox()
55
        self._vbox_buttons_bottom = gtk.VBox()
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
56
        self._vpaned = gtk.VPaned()
57
        
58
        # Set callbacks
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
59
        self._button_add.connect('clicked', self._on_add_clicked)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
60
        self._button_close.connect('clicked', self._on_close_clicked)
190.1.4 by Szilveszter Farkas (Phanatic)
Added Refresh button to the Tags window.
61
        self._button_refresh.connect('clicked', self._on_refresh_clicked)
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
62
        self._button_remove.connect('clicked', self._on_remove_clicked)
63
        self._treeview_tags.connect('cursor-changed', self._on_treeview_changed)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
64
        
65
        # Set properties
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
66
        self.set_title(_i18n("Tags"))
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
67
        self.set_default_size(600, 400)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
68
        
69
        self._scrolledwindow_tags.set_policy(gtk.POLICY_AUTOMATIC,
70
                                             gtk.POLICY_AUTOMATIC)
71
        
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
72
        self._hbox.set_border_width(5)
73
        self._hbox.set_spacing(5)
74
        self._vbox_buttons.set_size_request(100, -1)
75
        
76
        self._vbox_buttons_top.set_spacing(3)
77
        
78
        self._vpaned.set_position(200)
79
        
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
80
        # Construct the dialog
81
        self._scrolledwindow_tags.add(self._treeview_tags)
82
        
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
83
        self._vbox_buttons_top.pack_start(self._button_add, False, False)
84
        self._vbox_buttons_top.pack_start(self._button_remove, False, False)
190.1.4 by Szilveszter Farkas (Phanatic)
Added Refresh button to the Tags window.
85
        self._vbox_buttons_top.pack_start(self._button_refresh, False, False)
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
86
        self._vbox_buttons_bottom.pack_start(self._button_close, False, False)
87
        
88
        self._vbox_buttons.pack_start(self._vbox_buttons_top, True, True)
89
        self._vbox_buttons.pack_start(self._vbox_buttons_bottom, False, False)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
90
        
91
        self._vpaned.add1(self._scrolledwindow_tags)
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
92
        self._vpaned.add2(self._revisionview)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
93
        
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
94
        self._hbox.pack_start(self._vpaned, True, True)
95
        self._hbox.pack_start(self._vbox_buttons, False, True)
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
96
        
97
        self.add(self._hbox)
98
        
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
99
        # Default to no tags
100
        self._no_tags = True
101
        
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
102
        # Load the tags
103
        self._load_tags()
104
        
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
105
        # Display everything
106
        self._hbox.show_all()
107
    
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
108
    def _load_tags(self):
109
        """ Load the tags into the TreeView. """
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
110
        tvcol_name = gtk.TreeViewColumn(_i18n("Tag Name"),
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
111
                                        gtk.CellRendererText(),
112
                                        text=0)
113
        tvcol_name.set_resizable(True)
114
        
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
115
        tvcol_revid = gtk.TreeViewColumn(_i18n("Revision ID"),
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
116
                                         gtk.CellRendererText(),
117
                                         text=1)
118
        tvcol_revid.set_resizable(True)
119
        
120
        self._treeview_tags.append_column(tvcol_name)
121
        self._treeview_tags.append_column(tvcol_revid)
122
        
123
        self._treeview_tags.set_search_column(0)
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
124
        
125
        self._refresh_tags()
126
    
127
    def _refresh_tags(self):
128
        """ Refresh the list of tags. """
129
        self._model.clear()
130
        if self.branch.supports_tags():
131
            tags = self.branch.tags.get_tag_dict()
132
            if len(tags) > 0:
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
133
                self._no_tags = False
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
134
                for name, target in tags.items():
135
                    self._model.append([name, target])
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
136
                
137
                self._button_add.set_sensitive(True)
138
                self._button_remove.set_sensitive(True)
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
139
            else:
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
140
                self._no_tags = True
141
                self._no_tags_available()
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
142
        else:
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
143
            self._no_tags = True
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
144
            self._tags_not_supported()
145
        
146
        self._treeview_tags.set_model(self._model)
147
    
148
    def _tags_not_supported(self):
149
        """ Tags are not supported. """
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
150
        self._model.append([_i18n("Tags are not supported by this branch format. Please upgrade."), ""])
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
151
        self._button_add.set_sensitive(False)
152
        self._button_remove.set_sensitive(False)
153
    
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
154
    def _no_tags_available(self):
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
155
        """ No tags in the branch. """
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
156
        self._model.append([_i18n("No tagged revisions in the branch."), ""])
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
157
        self._button_add.set_sensitive(True)
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
158
        self._button_remove.set_sensitive(False)
159
    
160
    def _on_add_clicked(self, widget):
161
        """ Add button event handler. """
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
162
        dialog = AddTagDialog(self.branch.repository, None,
163
                              self.branch, self)
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
164
        response = dialog.run()
165
        if response != gtk.RESPONSE_NONE:
166
            dialog.hide()
167
        
168
            if response == gtk.RESPONSE_OK:
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
169
                self.branch.tags.set_tag(dialog.tagname, dialog._revid)
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
170
                self._refresh_tags()
171
            
172
            dialog.destroy()
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
173
    
190.1.1 by Szilveszter Farkas (Phanatic)
Added 'gtags' command and basic Tags window (just a skeleton).
174
    def _on_close_clicked(self, widget):
175
        """ Close button event handler. """
176
        self.destroy()
177
        if self._parent is None:
178
            gtk.main_quit()
275.1.5 by Daniel Schierbeck
Made windows close correctly on Ctrl-W and made the application quit on Ctrl-Q.
179
190.1.4 by Szilveszter Farkas (Phanatic)
Added Refresh button to the Tags window.
180
    def _on_refresh_clicked(self, widget):
181
        """ Refresh button event handler. """
182
        self._refresh_tags()
183
    
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
184
    def _on_remove_clicked(self, widget):
185
        """ Remove button event handler. """
186
        (path, col) = self._treeview_tags.get_cursor()
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
187
        if path is None:
188
            return
189
        
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
190
        tag = self._model[path][0]
191
        
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
192
        dialog = RemoveTagDialog(tag, self)
193
        response = dialog.run()
194
        if response != gtk.RESPONSE_NONE:
195
            dialog.hide()
196
        
197
            if response == gtk.RESPONSE_OK:
198
                self.branch.tags.delete_tag(tag)
199
                self._refresh_tags()
200
            
201
            dialog.destroy()
190.1.2 by Szilveszter Farkas (Phanatic)
Display list of tags.
202
    
203
    def _on_treeview_changed(self, *args):
204
        """ When a user clicks on a tag. """
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
205
        # Refresh RevisionView only if there are tags available
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
206
        if not self._no_tags:
207
            (path, col) = self._treeview_tags.get_cursor()
208
            revision = self._model[path][1]
209
            
330.3.1 by Daniel Schierbeck
Renamed logview 'revisionview'.
210
            self._revisionview.set_revision(self.branch.repository.get_revision(revision))
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
211
212
213
class RemoveTagDialog(gtk.Dialog):
214
    """ Confirm removal of tag. """
215
    def __init__(self, tagname, parent):
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
216
        gtk.Dialog.__init__(self, title="Remove tag",
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
217
                                  parent=parent,
218
                                  flags=0,
219
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
220
        
221
        # Get the arguments
222
        self.tag = tagname
223
        
224
        # Create the widgets
225
        self._hbox = gtk.HBox()
226
        self._vbox_question = gtk.VBox()
227
        self._image_question = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION,
228
                                                        gtk.ICON_SIZE_DIALOG)
229
        self._label_title = gtk.Label()
190.1.7 by Szilveszter Farkas (Phanatic)
Display tag name on the remove dialog.
230
        self._label_question = gtk.Label()
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
231
        self._button_remove = gtk.Button(_i18n("_Remove tag"), use_underline=True)
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
232
        
233
        # Set callbacks
234
        self._button_remove.connect('clicked', self._on_remove_clicked)
235
        
236
        # Set properties
237
        self._hbox.set_border_width(5)
238
        self._hbox.set_spacing(5)
239
        self._vbox_question.set_spacing(3)
240
        
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
241
        self._label_title.set_markup(_i18n("<b><big>Remove tag?</big></b>"))
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
242
        self._label_title.set_alignment(0.0, 0.5)
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
243
        self._label_question.set_markup(_i18n("Are you sure you want to remove the tag: <b>%s</b>?") % self.tag)
190.1.3 by Szilveszter Farkas (Phanatic)
Finalized Tags window layout. Added Remove confirmation dialog.
244
        self._label_question.set_alignment(0.0, 0.5)
245
        
246
        self._button_remove.set_image(gtk.image_new_from_stock(gtk.STOCK_REMOVE,
247
                                                               gtk.ICON_SIZE_BUTTON))
248
        self._button_remove.set_flags(gtk.CAN_DEFAULT)
249
        
250
        # Construct the dialog
251
        self._vbox_question.pack_start(self._label_title)
252
        self._vbox_question.pack_start(self._label_question)
253
        
254
        self._hbox.pack_start(self._image_question)
255
        self._hbox.pack_start(self._vbox_question)
256
        
257
        self.vbox.add(self._hbox)
258
        
259
        self.action_area.pack_end(self._button_remove)
260
        
261
        # Display dialog
262
        self.vbox.show_all()
263
        
264
        # Default to Commit button
265
        self._button_remove.grab_default()
266
    
267
    def _on_remove_clicked(self, widget):
268
        """ Remove button event handler. """
269
        self.response(gtk.RESPONSE_OK)
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
270
271
272
class AddTagDialog(gtk.Dialog):
273
    """ Add tag dialog. """
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
274
    def __init__(self, repository, revid=None, branch=None, parent=None):
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
275
        """ Initialize Add tag dialog. """
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
276
        gtk.Dialog.__init__(self, title="Add tag",
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
277
                                  parent=parent,
278
                                  flags=0,
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
279
                                  buttons=(gtk.STOCK_CANCEL, 
280
                                           gtk.RESPONSE_CANCEL))
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
281
        
282
        # Get arguments
231 by Jelmer Vernooij
Add RevisionSelectionBox widget, use in TagDialog.
283
        self._repository = repository
284
        self._revid = revid
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
285
        self._branch = branch
286
        
287
        # Create the widgets
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
288
        self._button_add = gtk.Button(_i18n("_Add tag"), use_underline=True)
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
289
        self._table = gtk.Table(2, 2)
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
290
        self._label_name = gtk.Label(_i18n("Tag Name:"))
291
        self._label_revid = gtk.Label(_i18n("Revision ID:"))
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
292
        self._entry_name = gtk.Entry()
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
293
        if self._revid is not None:
294
            self._hbox_revid = gtk.Label(self._revid)
295
        else:
296
            self._hbox_revid = RevisionSelectionBox(self._branch)
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
297
        
298
        # Set callbacks
299
        self._button_add.connect('clicked', self._on_add_clicked)
300
        
301
        # Set properties
302
        self._label_name.set_alignment(0, 0.5)
303
        self._label_revid.set_alignment(0, 0.5)
304
        self._button_add.set_image(gtk.image_new_from_stock(gtk.STOCK_ADD,
305
                                                            gtk.ICON_SIZE_BUTTON))
306
        self._button_add.set_flags(gtk.CAN_DEFAULT)
307
        
308
        # Construct the dialog
309
        self._table.attach(self._label_name, 0, 1, 0, 1)
310
        self._table.attach(self._label_revid, 0, 1, 1, 2)
311
        self._table.attach(self._entry_name, 1, 2, 0, 1)
312
        self._table.attach(self._hbox_revid, 1, 2, 1, 2)
313
        self.vbox.add(self._table)
314
        self.action_area.pack_end(self._button_add)
315
        
316
        # Show the dialog
317
        self.vbox.show_all()
318
    
319
    def _on_add_clicked(self, widget):
320
        """ Add button clicked handler. """
321
        if len(self._entry_name.get_text()) == 0:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
322
            error_dialog(_i18n("No tag name specified"),
323
                         _i18n("You have to specify the tag's desired name."))
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
324
            return
325
        
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
326
        if self._revid is None:
327
            if self._hbox_revid.get_revision_id() is None:
328
                self._revid = self._branch.last_revision()
329
            else:
487.3.1 by Javier Derderian
Fixed bug #228709. Can't add tag
330
                self._revid = self._hbox_revid.get_revision_id()
232 by Jelmer Vernooij
Make 'Add tag' dialog accessible from bzrk.
331
            
190.1.6 by Szilveszter Farkas (Phanatic)
Implemented Add tag dialog.
332
        self.tagname = self._entry_name.get_text()
333
        
334
        self.response(gtk.RESPONSE_OK)