/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to commit.py

  • Committer: John Arbash Meinel
  • Date: 2007-10-30 21:15:13 UTC
  • mfrom: (326 trunk)
  • mto: (330.3.3 trunk)
  • mto: This revision was merged to the branch mainline in revision 368.
  • Revision ID: john@arbash-meinel.com-20071030211513-l8ukdfa81g1y74mi
Merge the latest trunk 326

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
import os.path
18
 
import re
19
 
 
20
17
try:
21
18
    import pygtk
22
19
    pygtk.require("2.0")
27
24
import gobject
28
25
import pango
29
26
 
 
27
import os.path
 
28
import re
 
29
 
30
30
from bzrlib import errors, osutils
31
31
from bzrlib.trace import mutter
32
32
from bzrlib.util import bencode
33
33
 
34
 
from bzrlib.plugins.gtk import _i18n
35
 
from bzrlib.plugins.gtk.dialog import question_dialog
36
 
from bzrlib.plugins.gtk.errors import show_bzr_error
 
34
from dialog import error_dialog, question_dialog
 
35
from errors import show_bzr_error
37
36
 
38
37
try:
39
38
    import dbus
97
96
    return pm
98
97
 
99
98
 
100
 
_newline_variants_re = re.compile(r'\r\n?')
101
 
def _sanitize_and_decode_message(utf8_message):
102
 
    """Turn a utf-8 message into a sanitized Unicode message."""
103
 
    fixed_newline = _newline_variants_re.sub('\n', utf8_message)
104
 
    return fixed_newline.decode('utf-8')
105
 
 
106
 
 
107
99
class CommitDialog(gtk.Dialog):
108
100
    """Implementation of Commit."""
109
101
 
110
102
    def __init__(self, wt, selected=None, parent=None):
111
 
        gtk.Dialog.__init__(self, title="Commit to %s" % wt.basedir,
 
103
        gtk.Dialog.__init__(self, title="Commit - Olive",
112
104
                                  parent=parent,
113
105
                                  flags=0,
114
 
                                  buttons=(gtk.STOCK_CANCEL,
115
 
                                           gtk.RESPONSE_CANCEL))
 
106
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
116
107
        self._question_dialog = question_dialog
117
 
        
118
 
        self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
119
108
 
120
109
        self._wt = wt
121
110
        # TODO: Do something with this value, it is used by Olive
122
111
        #       It used to set all changes but this one to False
123
112
        self._selected = selected
124
113
        self._enable_per_file_commits = True
125
 
        self._commit_all_changes = True
126
114
        self.committed_revision_id = None # Nothing has been committed yet
127
115
 
128
116
        self.setup_params()
175
163
        store = self._files_store
176
164
        self._treeview_files.set_model(None)
177
165
 
178
 
        added = _i18n('added')
179
 
        removed = _i18n('removed')
180
 
        renamed = _i18n('renamed')
181
 
        renamed_and_modified = _i18n('renamed and modified')
182
 
        modified = _i18n('modified')
183
 
        kind_changed = _i18n('kind changed')
 
166
        added = _('added')
 
167
        removed = _('removed')
 
168
        renamed = _('renamed')
 
169
        renamed_and_modified = _('renamed and modified')
 
170
        modified = _('modified')
 
171
        kind_changed = _('kind changed')
184
172
 
185
173
        # The store holds:
186
174
        # [file_id, real path, checkbox, display path, changes type, message]
187
 
        # iter_changes returns:
 
175
        # _iter_changes returns:
188
176
        # (file_id, (path_in_source, path_in_target),
189
177
        #  changed_content, versioned, parent, name, kind,
190
178
        #  executable)
197
185
        self._wt.lock_read()
198
186
        self._basis_tree.lock_read()
199
187
        try:
200
 
            from diff import iter_changes_to_status
 
188
            from diff import _iter_changes_to_status
201
189
            for (file_id, real_path, change_type, display_path
202
 
                ) in iter_changes_to_status(self._basis_tree, self._wt):
 
190
                ) in _iter_changes_to_status(self._basis_tree, self._wt):
203
191
                if self._selected and real_path != self._selected:
204
192
                    enabled = False
205
193
                else:
238
226
            return
239
227
        if have_dbus:
240
228
            bus = dbus.SystemBus()
241
 
            try:
242
 
                proxy_obj = bus.get_object('org.freedesktop.NetworkManager',
243
 
                                           '/org/freedesktop/NetworkManager')
244
 
            except dbus.DBusException:
245
 
                mutter("networkmanager not available.")
246
 
                self._check_local.show()
247
 
                return
248
 
            
 
229
            proxy_obj = bus.get_object('org.freedesktop.NetworkManager',
 
230
                                       '/org/freedesktop/NetworkManager')
249
231
            dbus_iface = dbus.Interface(proxy_obj,
250
232
                                        'org.freedesktop.NetworkManager')
251
233
            try:
268
250
            self._enable_per_file_commits = True
269
251
        if not self._enable_per_file_commits:
270
252
            self._file_message_expander.hide()
271
 
            self._global_message_label.set_markup(_i18n('<b>Commit Message</b>'))
272
253
 
273
254
    def _compute_delta(self):
274
255
        self._delta = self._wt.changes_from(self._basis_tree)
313
294
                            gtk.gdk.CONTROL_MASK, 0, self._on_accel_next)
314
295
        self.add_accel_group(group)
315
296
 
316
 
        # ignore the escape key (avoid closing the window)
317
 
        self.connect_object('close', self.emit_stop_by_name, 'close')
318
 
 
319
297
    def _construct_left_pane(self):
320
298
        self._left_pane_box = gtk.VBox(homogeneous=False, spacing=5)
321
299
        self._construct_file_list()
322
300
        self._construct_pending_list()
323
301
 
324
 
        self._check_local = gtk.CheckButton(_i18n("_Only commit locally"),
 
302
        self._check_local = gtk.CheckButton(_("_Only commit locally"),
325
303
                                            use_underline=True)
326
304
        self._left_pane_box.pack_end(self._check_local, False, False)
327
305
        self._check_local.set_active(False)
348
326
        self._hpane.pack2(self._right_pane_table, resize=True, shrink=True)
349
327
 
350
328
    def _construct_action_pane(self):
351
 
        self._button_commit = gtk.Button(_i18n("Comm_it"), use_underline=True)
 
329
        self._button_commit = gtk.Button(_("Comm_it"), use_underline=True)
352
330
        self._button_commit.connect('clicked', self._on_commit_clicked)
353
331
        self._button_commit.set_flags(gtk.CAN_DEFAULT)
354
332
        self._button_commit.show()
374
352
 
375
353
    def _construct_file_list(self):
376
354
        self._files_box = gtk.VBox(homogeneous=False, spacing=0)
377
 
        file_label = gtk.Label(_i18n('Files'))
378
 
        # file_label.show()
 
355
        file_label = gtk.Label(_('Files'))
 
356
        file_label.show()
379
357
        self._files_box.pack_start(file_label, expand=False)
380
358
 
381
 
        self._commit_all_files_radio = gtk.RadioButton(
382
 
            None, _i18n("Commit all changes"))
383
 
        self._files_box.pack_start(self._commit_all_files_radio, expand=False)
384
 
        self._commit_all_files_radio.show()
385
 
        self._commit_all_files_radio.connect('toggled',
386
 
            self._toggle_commit_selection)
387
 
        self._commit_selected_radio = gtk.RadioButton(
388
 
            self._commit_all_files_radio, _i18n("Only commit selected changes"))
389
 
        self._files_box.pack_start(self._commit_selected_radio, expand=False)
390
 
        self._commit_selected_radio.show()
391
 
        self._commit_selected_radio.connect('toggled',
392
 
            self._toggle_commit_selection)
393
 
        if self._pending:
394
 
            self._commit_all_files_radio.set_label(_i18n('Commit all changes*'))
395
 
            self._commit_all_files_radio.set_sensitive(False)
396
 
            self._commit_selected_radio.set_sensitive(False)
397
 
 
398
359
        scroller = gtk.ScrolledWindow()
399
360
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
400
361
        self._treeview_files = gtk.TreeView()
421
382
        self._files_store = liststore
422
383
        self._treeview_files.set_model(liststore)
423
384
        crt = gtk.CellRendererToggle()
424
 
        crt.set_property('activatable', not bool(self._pending))
 
385
        crt.set_active(not bool(self._pending))
425
386
        crt.connect("toggled", self._toggle_commit, self._files_store)
426
387
        if self._pending:
427
 
            name = _i18n('Commit*')
 
388
            name = _('Commit*')
428
389
        else:
429
 
            name = _i18n('Commit')
430
 
        commit_col = gtk.TreeViewColumn(name, crt, active=2)
431
 
        commit_col.set_visible(False)
432
 
        self._treeview_files.append_column(commit_col)
433
 
        self._treeview_files.append_column(gtk.TreeViewColumn(_i18n('Path'),
 
390
            name = _('Commit')
 
391
        self._treeview_files.append_column(gtk.TreeViewColumn(name,
 
392
                                           crt, active=2))
 
393
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Path'),
434
394
                                           gtk.CellRendererText(), text=3))
435
 
        self._treeview_files.append_column(gtk.TreeViewColumn(_i18n('Type'),
 
395
        self._treeview_files.append_column(gtk.TreeViewColumn(_('Type'),
436
396
                                           gtk.CellRendererText(), text=4))
437
397
        self._treeview_files.connect('cursor-changed',
438
398
                                     self._on_treeview_files_cursor_changed)
445
405
        else:
446
406
            model[path][2] = not model[path][2]
447
407
 
448
 
    def _toggle_commit_selection(self, button):
449
 
        all_files = self._commit_all_files_radio.get_active()
450
 
        if self._commit_all_changes != all_files:
451
 
            checked_col = self._treeview_files.get_column(0)
452
 
            self._commit_all_changes = all_files
453
 
            if all_files:
454
 
                checked_col.set_visible(False)
455
 
            else:
456
 
                checked_col.set_visible(True)
457
 
            renderer = checked_col.get_cell_renderers()[0]
458
 
            renderer.set_property('activatable', not all_files)
459
 
 
460
408
    def _construct_pending_list(self):
461
409
        # Pending information defaults to hidden, we put it all in 1 box, so
462
410
        # that we can show/hide all of them at once
465
413
 
466
414
        pending_message = gtk.Label()
467
415
        pending_message.set_markup(
468
 
            _i18n('<i>* Cannot select specific files when merging</i>'))
 
416
            _('<i>* Cannot select specific files when merging</i>'))
469
417
        self._pending_box.pack_start(pending_message, expand=False, padding=5)
470
418
        pending_message.show()
471
419
 
472
 
        pending_label = gtk.Label(_i18n('Pending Revisions'))
 
420
        pending_label = gtk.Label(_('Pending Revisions'))
473
421
        self._pending_box.pack_start(pending_label, expand=False, padding=0)
474
422
        pending_label.show()
475
423
 
491
439
                                 )
492
440
        self._pending_store = liststore
493
441
        self._treeview_pending.set_model(liststore)
494
 
        self._treeview_pending.append_column(gtk.TreeViewColumn(_i18n('Date'),
 
442
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Date'),
495
443
                                             gtk.CellRendererText(), text=1))
496
 
        self._treeview_pending.append_column(gtk.TreeViewColumn(_i18n('Committer'),
 
444
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Committer'),
497
445
                                             gtk.CellRendererText(), text=2))
498
 
        self._treeview_pending.append_column(gtk.TreeViewColumn(_i18n('Summary'),
 
446
        self._treeview_pending.append_column(gtk.TreeViewColumn(_('Summary'),
499
447
                                             gtk.CellRendererText(), text=3))
500
448
 
501
449
    def _construct_diff_view(self):
502
450
        from diff import DiffView
503
451
 
504
 
        # TODO: jam 2007-10-30 The diff label is currently disabled. If we
505
 
        #       decide that we really don't ever want to display it, we should
506
 
        #       actually remove it, and other references to it, along with the
507
 
        #       tests that it is set properly.
508
 
        self._diff_label = gtk.Label(_i18n('Diff for whole tree'))
 
452
        self._diff_label = gtk.Label(_('Diff for whole tree'))
509
453
        self._diff_label.set_alignment(0, 0)
510
454
        self._right_pane_table.set_row_spacing(self._right_pane_table_row, 0)
511
455
        self._add_to_right_table(self._diff_label, 1, False)
512
 
        # self._diff_label.show()
 
456
        self._diff_label.show()
513
457
 
514
458
        self._diff_view = DiffView()
515
459
        self._add_to_right_table(self._diff_view, 4, True)
529
473
        self._file_message_text_view.set_accepts_tab(False)
530
474
        self._file_message_text_view.show()
531
475
 
532
 
        self._file_message_expander = gtk.Expander(_i18n('File commit message'))
 
476
        self._file_message_expander = gtk.Expander(_('File commit message'))
533
477
        self._file_message_expander.set_expanded(True)
534
478
        self._file_message_expander.add(scroller)
535
479
        self._add_to_right_table(self._file_message_expander, 1, False)
536
480
        self._file_message_expander.show()
537
481
 
538
482
    def _construct_global_message(self):
539
 
        self._global_message_label = gtk.Label(_i18n('Global Commit Message'))
540
 
        self._global_message_label.set_markup(
541
 
            _i18n('<b>Global Commit Message</b>'))
 
483
        self._global_message_label = gtk.Label(_('Global Commit Message'))
542
484
        self._global_message_label.set_alignment(0, 0)
543
485
        self._right_pane_table.set_row_spacing(self._right_pane_table_row, 0)
544
486
        self._add_to_right_table(self._global_message_label, 1, False)
564
506
 
565
507
        if selection is not None:
566
508
            path, display_path = model.get(selection, 1, 3)
567
 
            self._diff_label.set_text(_i18n('Diff for ') + display_path)
 
509
            self._diff_label.set_text(_('Diff for ') + display_path)
568
510
            if path is None:
569
511
                self._diff_view.show_diff(None)
570
512
            else:
611
553
        text_buffer = self._file_message_text_view.get_buffer()
612
554
        file_id, display_path, message = self._files_store.get(selection, 0, 3, 5)
613
555
        if file_id is None: # Whole tree
614
 
            self._file_message_expander.set_label(_i18n('File commit message'))
 
556
            self._file_message_expander.set_label(_('File commit message'))
615
557
            self._file_message_expander.set_expanded(False)
616
558
            self._file_message_expander.set_sensitive(False)
617
559
            text_buffer.set_text('')
618
560
            self._last_selected_file = None
619
561
        else:
620
 
            self._file_message_expander.set_label(_i18n('Commit message for ')
 
562
            self._file_message_expander.set_label(_('Commit message for ')
621
563
                                                  + display_path)
622
564
            self._file_message_expander.set_expanded(True)
623
565
            self._file_message_expander.set_sensitive(True)
637
579
 
638
580
        file_info = []
639
581
        for record in records:
640
 
            if self._commit_all_changes or record[2]:# [2] checkbox
 
582
            if record[2]:           # [2] checkbox
641
583
                file_id = record[0] # [0] file_id
642
584
                path = record[1]    # [1] real path
643
 
                # [5] commit message
644
 
                file_message = _sanitize_and_decode_message(record[5])
 
585
                file_message = record[5] # [5] commit message
645
586
                files.append(path.decode('UTF-8'))
646
587
                if self._enable_per_file_commits and file_message:
647
588
                    # All of this needs to be utf-8 information
648
 
                    file_message = file_message.encode('UTF-8')
649
589
                    file_info.append({'path':path, 'file_id':file_id,
650
590
                                     'message':file_message})
651
591
        file_info.sort(key=lambda x:(x['path'], x['file_id']))
664
604
 
665
605
        if message == '':
666
606
            response = self._question_dialog(
667
 
                _i18n('Commit with an empty message?'),
668
 
                _i18n('You can describe your commit intent in the message.'),
669
 
                parent=self)
 
607
                            _('Commit with an empty message?'),
 
608
                            _('You can describe your commit intent in the message.'))
670
609
            if response == gtk.RESPONSE_NO:
671
610
                # Kindly give focus to message area
672
611
                self._global_message_text_view.grab_focus()
685
624
        #       files at this point.
686
625
        for path in self._wt.unknowns():
687
626
            response = self._question_dialog(
688
 
                _i18n("Commit with unknowns?"),
689
 
                _i18n("Unknown files exist in the working tree. Commit anyway?"),
690
 
                parent=self)
691
 
                # Doesn't set a parent for the dialog..
 
627
                _("Commit with unknowns?"),
 
628
                _("Unknown files exist in the working tree. Commit anyway?"))
692
629
            if response == gtk.RESPONSE_NO:
693
630
                return
694
631
            break
706
643
                       revprops=revprops)
707
644
        except errors.PointlessCommit:
708
645
            response = self._question_dialog(
709
 
                _i18n('Commit with no changes?'),
710
 
                _i18n('There are no changes in the working tree.'
711
 
                      ' Do you want to commit anyway?'),
712
 
                parent=self)
 
646
                                _('Commit with no changes?'),
 
647
                                _('There are no changes in the working tree.'
 
648
                                  ' Do you want to commit anyway?'))
713
649
            if response == gtk.RESPONSE_YES:
714
650
                rev_id = self._wt.commit(message,
715
651
                               allow_pointless=True,
723
659
    def _get_global_commit_message(self):
724
660
        buf = self._global_message_text_view.get_buffer()
725
661
        start, end = buf.get_bounds()
726
 
        text = buf.get_text(start, end)
727
 
        return _sanitize_and_decode_message(text)
 
662
        return buf.get_text(start, end).decode('utf-8')
728
663
 
729
664
    def _set_global_commit_message(self, message):
730
665
        """Just a helper for the test suite."""