[Pkg-bazaar-commits] ./bzr-gtk/unstable r193: Implemented tags support.

Szilveszter Farkas (Phanatic) Szilveszter.Farkas at gmail.com
Fri Apr 10 07:45:35 UTC 2009


------------------------------------------------------------
revno: 193
committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
branch nick: trunk
timestamp: Sun 2007-04-22 22:38:34 +0200
message:
  Implemented tags support.
added:
  tags.py
modified:
  NEWS
  __init__.py
  olive.glade
  olive/__init__.py
  revbrowser.py
    ------------------------------------------------------------
    revno: 190.1.1
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Sun 2007-04-08 23:08:06 +0200
    message:
      Added 'gtags' command and basic Tags window (just a skeleton).
    added:
      tags.py
    modified:
      __init__.py
    ------------------------------------------------------------
    revno: 190.1.2
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Tue 2007-04-10 00:03:11 +0200
    message:
      Display list of tags.
    modified:
      tags.py
    ------------------------------------------------------------
    revno: 190.1.3
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Fri 2007-04-13 19:10:04 +0200
    message:
      Finalized Tags window layout. Added Remove confirmation dialog.
    modified:
      tags.py
    ------------------------------------------------------------
    revno: 190.1.4
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Sat 2007-04-14 18:33:22 +0200
    message:
      Added Refresh button to the Tags window.
    modified:
      tags.py
    ------------------------------------------------------------
    revno: 190.1.5
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Sun 2007-04-15 22:24:40 +0200
    message:
      Revision Browser now provides revision ID.
    modified:
      revbrowser.py
    ------------------------------------------------------------
    revno: 190.1.6
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Mon 2007-04-16 16:31:26 +0200
    message:
      Implemented Add tag dialog.
    modified:
      tags.py
    ------------------------------------------------------------
    revno: 190.1.7
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Tue 2007-04-17 00:14:51 +0200
    message:
      Display tag name on the remove dialog.
    modified:
      tags.py
    ------------------------------------------------------------
    revno: 190.1.8
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Wed 2007-04-18 13:40:10 +0200
    message:
      Added Tags entry to the Branch menu in Olive.
    modified:
      olive.glade
      olive/__init__.py
    ------------------------------------------------------------
    revno: 190.1.9
    committer: Szilveszter Farkas (Phanatic) <Szilveszter.Farkas at gmail.com>
    branch nick: bzr-gtk.tags
    timestamp: Sun 2007-04-22 22:37:17 +0200
    message:
      Added NEWS entry.
    modified:
      NEWS
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2007-04-07 07:43:25 +0000
+++ b/NEWS	2007-04-22 20:37:17 +0000
@@ -4,6 +4,9 @@
  
   * An Initialize dialog added to Olive along with a 'ginit' command
   (#90839, Szilveszter)
+  
+  * Tags support added: 'gtags' command and Branch->Tags menu entry in Olive
+  (#103725, Szilveszter)
 
 0.15.2	2007-04-03
 

=== modified file '__init__.py'
--- a/__init__.py	2007-04-06 17:16:31 +0000
+++ b/__init__.py	2007-04-08 21:08:06 +0000
@@ -427,6 +427,17 @@
         dialog.run()
 
 
+class cmd_gtags(GTKCommand):
+    def run(self):
+        br = branch.Branch.open_containing('.')[0]
+        
+        gtk = self.open_display()
+        from tags import TagsWindow
+        window = TagsWindow(br)
+        window.show()
+        gtk.main()
+
+
 commands = [
     cmd_gmissing, 
     cmd_gpreferences, 
@@ -439,7 +450,8 @@
     cmd_gpush, 
     cmd_gcheckout, 
     cmd_gbranch,
-    cmd_ginit
+    cmd_ginit,
+    cmd_gtags
     ]
 
 for cmd in commands:

=== modified file 'olive.glade'
--- a/olive.glade	2007-04-06 17:59:23 +0000
+++ b/olive.glade	2007-04-18 11:40:10 +0000
@@ -325,6 +325,15 @@
 		  </child>
 
 		  <child>
+		    <widget class="GtkMenuItem" id="menuitem_branch_tags">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Ta_gs...</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="on_menuitem_branch_tags_activate" last_modification_time="Wed, 18 Apr 2007 13:31:06 GMT"/>
+		    </widget>
+		  </child>
+		  
+		  <child>
 		    <widget class="GtkMenuItem" id="menuitem_branch_status">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">S_tatus...</property>

=== modified file 'olive/__init__.py'
--- a/olive/__init__.py	2007-04-06 17:59:23 +0000
+++ b/olive/__init__.py	2007-04-18 11:40:10 +0000
@@ -89,6 +89,7 @@
         self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
         self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
         self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
+        self.menuitem_branch_tags = self.toplevel.get_widget('menuitem_branch_tags')
         self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
         self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
         self.menuitem_branch_conflicts = self.toplevel.get_widget('menuitem_branch_conflicts')
@@ -130,6 +131,7 @@
                 "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
                 "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
                 "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
+                "on_menuitem_branch_tags_activate": self.on_menuitem_branch_tags_activate,
                 "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
                 "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
                 "on_menuitem_branch_conflicts_activate": self.on_menuitem_branch_conflicts_activate,
@@ -356,6 +358,12 @@
             
             init.destroy()
         
+    def on_menuitem_branch_tags_activate(self, widget):
+        """ Branch/Tags... menu handler. """
+        from bzrlib.plugins.gtk.tags import TagsWindow
+        window = TagsWindow(self.wt.branch, self.window)
+        window.show()
+    
     def on_menuitem_file_annotate_activate(self, widget):
         """ File/Annotate... menu handler. """
         if self.get_selected_right() is None:
@@ -729,6 +737,7 @@
         self.menuitem_branch_revert.set_sensitive(not self.notbranch)
         self.menuitem_branch_merge.set_sensitive(not self.notbranch)
         self.menuitem_branch_commit.set_sensitive(not self.notbranch)
+        self.menuitem_branch_tags.set_sensitive(not self.notbranch)
         self.menuitem_branch_status.set_sensitive(not self.notbranch)
         self.menuitem_branch_missing.set_sensitive(not self.notbranch)
         self.menuitem_branch_conflicts.set_sensitive(not self.notbranch)

=== modified file 'revbrowser.py'
--- a/revbrowser.py	2007-02-03 11:52:13 +0000
+++ b/revbrowser.py	2007-04-15 20:24:40 +0000
@@ -82,10 +82,11 @@
 
     def _fill_revisions(self):
         """ Fill up the treeview with the revisions. """
-        # [ revno, message, committer, timestamp ]
+        # [ revno, message, committer, timestamp, revid ]
         self.model = gtk.ListStore(gobject.TYPE_STRING,
                                    gobject.TYPE_STRING,
                                    gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING,
                                    gobject.TYPE_STRING)
         self._treeview.set_model(self.model)
         repo = self.branch.repository
@@ -100,7 +101,8 @@
             self.model.append([ self.branch.revision_id_to_revno(rev.revision_id),
                                 rev.get_summary(),
                                 rev.committer,
-                                timestamp ])
+                                timestamp,
+                                rev.revision_id ])
     
     def _get_selected_revno(self):
         """ Return the selected revision's revno. """
@@ -112,6 +114,16 @@
         else:
             return model.get_value(iter, 0)
     
+    def _get_selected_revid(self):
+        """ Return the selected revision's revid. """
+        treeselection = self._treeview.get_selection()
+        (model, iter) = treeselection.get_selected()
+        
+        if iter is None:
+            return None
+        else:
+            return model.get_value(iter, 4)
+    
     def _on_treeview_row_activated(self, treeview, path, column):
         """ Double-click on a row should also select a revision. """
         self._on_select_clicked(treeview)
@@ -119,4 +131,5 @@
     def _on_select_clicked(self, widget):
         """ Select button clicked handler. """
         self.selected_revno = self._get_selected_revno()
+        self.selected_revid = self._get_selected_revid()
         self.response(gtk.RESPONSE_OK)

=== added file 'tags.py'
--- a/tags.py	1970-01-01 00:00:00 +0000
+++ b/tags.py	2007-04-16 22:14:51 +0000
@@ -0,0 +1,347 @@
+# Copyright (C) 2007 by Szilveszter Farkas (Phanatic) <szilveszter.farkas at gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+try:
+    import pygtk
+    pygtk.require("2.0")
+except:
+    pass
+
+import gtk
+
+from bzrlib.plugins.gtk.logview import LogView
+
+from dialog import error_dialog
+
+
+class TagsWindow(gtk.Window):
+    """ Tags window. Allows the user to view/add/remove tags. """
+    def __init__(self, branch, parent=None):
+        """ Initialize the Tags window. """
+        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
+        
+        # Get arguments
+        self.branch = branch
+        self._parent = parent
+        
+        # Create the widgets
+        self._button_add = gtk.Button(stock=gtk.STOCK_ADD)
+        self._button_remove = gtk.Button(stock=gtk.STOCK_REMOVE)
+        self._button_refresh = gtk.Button(stock=gtk.STOCK_REFRESH)
+        self._button_close = gtk.Button(stock=gtk.STOCK_CLOSE)
+        self._model = gtk.ListStore(str, str)
+        self._treeview_tags = gtk.TreeView(self._model)
+        self._scrolledwindow_tags = gtk.ScrolledWindow()
+        self._logview = LogView()
+        self._hbox = gtk.HBox()
+        self._vbox_buttons = gtk.VBox()
+        self._vbox_buttons_top = gtk.VBox()
+        self._vbox_buttons_bottom = gtk.VBox()
+        self._vpaned = gtk.VPaned()
+        
+        # Set callbacks
+        self._button_add.connect('clicked', self._on_add_clicked)
+        self._button_close.connect('clicked', self._on_close_clicked)
+        self._button_refresh.connect('clicked', self._on_refresh_clicked)
+        self._button_remove.connect('clicked', self._on_remove_clicked)
+        self._treeview_tags.connect('cursor-changed', self._on_treeview_changed)
+        if parent is None:
+            self.connect('delete-event', gtk.main_quit)
+        
+        # Set properties
+        self.set_title(_("Tags - Olive"))
+        self.set_default_size(600, 400)
+        
+        self._scrolledwindow_tags.set_policy(gtk.POLICY_AUTOMATIC,
+                                             gtk.POLICY_AUTOMATIC)
+        
+        self._hbox.set_border_width(5)
+        self._hbox.set_spacing(5)
+        self._vbox_buttons.set_size_request(100, -1)
+        
+        self._vbox_buttons_top.set_spacing(3)
+        
+        self._vpaned.set_position(200)
+        
+        # Construct the dialog
+        self._scrolledwindow_tags.add(self._treeview_tags)
+        
+        self._vbox_buttons_top.pack_start(self._button_add, False, False)
+        self._vbox_buttons_top.pack_start(self._button_remove, False, False)
+        self._vbox_buttons_top.pack_start(self._button_refresh, False, False)
+        self._vbox_buttons_bottom.pack_start(self._button_close, False, False)
+        
+        self._vbox_buttons.pack_start(self._vbox_buttons_top, True, True)
+        self._vbox_buttons.pack_start(self._vbox_buttons_bottom, False, False)
+        
+        self._vpaned.add1(self._scrolledwindow_tags)
+        self._vpaned.add2(self._logview)
+        
+        self._hbox.pack_start(self._vpaned, True, True)
+        self._hbox.pack_start(self._vbox_buttons, False, True)
+        
+        self.add(self._hbox)
+        
+        # Default to no tags
+        self._no_tags = True
+        
+        # Load the tags
+        self._load_tags()
+        
+        # Display everything
+        self._hbox.show_all()
+    
+    def _load_tags(self):
+        """ Load the tags into the TreeView. """
+        tvcol_name = gtk.TreeViewColumn(_("Tag Name"),
+                                        gtk.CellRendererText(),
+                                        text=0)
+        tvcol_name.set_resizable(True)
+        
+        tvcol_revid = gtk.TreeViewColumn(_("Revision ID"),
+                                         gtk.CellRendererText(),
+                                         text=1)
+        tvcol_revid.set_resizable(True)
+        
+        self._treeview_tags.append_column(tvcol_name)
+        self._treeview_tags.append_column(tvcol_revid)
+        
+        self._treeview_tags.set_search_column(0)
+        
+        self._refresh_tags()
+    
+    def _refresh_tags(self):
+        """ Refresh the list of tags. """
+        self._model.clear()
+        if self.branch.supports_tags():
+            tags = self.branch.tags.get_tag_dict()
+            if len(tags) > 0:
+                self._no_tags = False
+                for name, target in tags.items():
+                    self._model.append([name, target])
+                
+                self._button_add.set_sensitive(True)
+                self._button_remove.set_sensitive(True)
+            else:
+                self._no_tags = True
+                self._no_tags_available()
+        else:
+            self._no_tags = True
+            self._tags_not_supported()
+        
+        self._treeview_tags.set_model(self._model)
+    
+    def _tags_not_supported(self):
+        """ Tags are not supported. """
+        self._model.append([_("Tags are not supported by this branch format. Please upgrade."), ""])
+        self._button_add.set_sensitive(False)
+        self._button_remove.set_sensitive(False)
+    
+    def _no_tags_available(self):
+        """ No tags in the branch. """
+        self._model.append([_("No tagged revisions in the branch."), ""])
+        self._button_add.set_sensitive(True)
+        self._button_remove.set_sensitive(False)
+    
+    def _on_add_clicked(self, widget):
+        """ Add button event handler. """
+        dialog = AddTagDialog(self.branch, self)
+        response = dialog.run()
+        if response != gtk.RESPONSE_NONE:
+            dialog.hide()
+        
+            if response == gtk.RESPONSE_OK:
+                self.branch.tags.set_tag(dialog.tagname, dialog.revid)
+                self._refresh_tags()
+            
+            dialog.destroy()
+    
+    def _on_close_clicked(self, widget):
+        """ Close button event handler. """
+        self.destroy()
+        if self._parent is None:
+            gtk.main_quit()
+    
+    def _on_refresh_clicked(self, widget):
+        """ Refresh button event handler. """
+        self._refresh_tags()
+    
+    def _on_remove_clicked(self, widget):
+        """ Remove button event handler. """
+        (path, col) = self._treeview_tags.get_cursor()
+        if path is None:
+            return
+        
+        tag = self._model[path][0]
+        
+        dialog = RemoveTagDialog(tag, self)
+        response = dialog.run()
+        if response != gtk.RESPONSE_NONE:
+            dialog.hide()
+        
+            if response == gtk.RESPONSE_OK:
+                self.branch.tags.delete_tag(tag)
+                self._refresh_tags()
+            
+            dialog.destroy()
+    
+    def _on_treeview_changed(self, *args):
+        """ When a user clicks on a tag. """
+        # Refresh LogView only if there are tags available
+        if not self._no_tags:
+            (path, col) = self._treeview_tags.get_cursor()
+            revision = self._model[path][1]
+            
+            self._logview.set_revision(self.branch.repository.get_revision(revision))
+
+
+class RemoveTagDialog(gtk.Dialog):
+    """ Confirm removal of tag. """
+    def __init__(self, tagname, parent):
+        gtk.Dialog.__init__(self, title="Remove tag - Olive",
+                                  parent=parent,
+                                  flags=0,
+                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+        
+        # Get the arguments
+        self.tag = tagname
+        
+        # Create the widgets
+        self._hbox = gtk.HBox()
+        self._vbox_question = gtk.VBox()
+        self._image_question = gtk.image_new_from_stock(gtk.STOCK_DIALOG_QUESTION,
+                                                        gtk.ICON_SIZE_DIALOG)
+        self._label_title = gtk.Label()
+        self._label_question = gtk.Label()
+        self._button_remove = gtk.Button(_("_Remove tag"), use_underline=True)
+        
+        # Set callbacks
+        self._button_remove.connect('clicked', self._on_remove_clicked)
+        
+        # Set properties
+        self._hbox.set_border_width(5)
+        self._hbox.set_spacing(5)
+        self._vbox_question.set_spacing(3)
+        
+        self._label_title.set_markup(_("<b><big>Remove tag?</big></b>"))
+        self._label_title.set_alignment(0.0, 0.5)
+        self._label_question.set_markup(_("Are you sure you want to remove the tag: <b>%s</b>?") % self.tag)
+        self._label_question.set_alignment(0.0, 0.5)
+        
+        self._button_remove.set_image(gtk.image_new_from_stock(gtk.STOCK_REMOVE,
+                                                               gtk.ICON_SIZE_BUTTON))
+        self._button_remove.set_flags(gtk.CAN_DEFAULT)
+        
+        # Construct the dialog
+        self._vbox_question.pack_start(self._label_title)
+        self._vbox_question.pack_start(self._label_question)
+        
+        self._hbox.pack_start(self._image_question)
+        self._hbox.pack_start(self._vbox_question)
+        
+        self.vbox.add(self._hbox)
+        
+        self.action_area.pack_end(self._button_remove)
+        
+        # Display dialog
+        self.vbox.show_all()
+        
+        # Default to Commit button
+        self._button_remove.grab_default()
+    
+    def _on_remove_clicked(self, widget):
+        """ Remove button event handler. """
+        self.response(gtk.RESPONSE_OK)
+
+
+class AddTagDialog(gtk.Dialog):
+    """ Add tag dialog. """
+    def __init__(self, branch, parent):
+        """ Initialize Add tag dialog. """
+        gtk.Dialog.__init__(self, title="Add tag - Olive",
+                                  parent=parent,
+                                  flags=0,
+                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+        
+        # Get arguments
+        self._branch = branch
+        
+        # Create the widgets
+        self._button_add = gtk.Button(_("_Add tag"), use_underline=True)
+        self._button_revid = gtk.Button('')
+        self._table = gtk.Table(2, 2)
+        self._label_name = gtk.Label(_("Tag Name:"))
+        self._label_revid = gtk.Label(_("Revision ID:"))
+        self._entry_name = gtk.Entry()
+        self._entry_revid = gtk.Entry()
+        self._hbox_revid = gtk.HBox()
+        
+        # Set callbacks
+        self._button_add.connect('clicked', self._on_add_clicked)
+        self._button_revid.connect('clicked', self._on_revid_clicked)
+        
+        # Set properties
+        self._label_name.set_alignment(0, 0.5)
+        self._label_revid.set_alignment(0, 0.5)
+        self._button_add.set_image(gtk.image_new_from_stock(gtk.STOCK_ADD,
+                                                            gtk.ICON_SIZE_BUTTON))
+        self._button_revid.set_image(gtk.image_new_from_stock(gtk.STOCK_OPEN,
+                                                               gtk.ICON_SIZE_BUTTON))
+        self._button_add.set_flags(gtk.CAN_DEFAULT)
+        
+        # Construct the dialog
+        self._hbox_revid.pack_start(self._entry_revid, True, True)
+        self._hbox_revid.pack_start(self._button_revid, False, False) 
+        self._table.attach(self._label_name, 0, 1, 0, 1)
+        self._table.attach(self._label_revid, 0, 1, 1, 2)
+        self._table.attach(self._entry_name, 1, 2, 0, 1)
+        self._table.attach(self._hbox_revid, 1, 2, 1, 2)
+        self.vbox.add(self._table)
+        self.action_area.pack_end(self._button_add)
+        
+        # Show the dialog
+        self.vbox.show_all()
+    
+    def _on_revid_clicked(self, widget):
+        """ Browse for revision button clicked handler. """
+        from revbrowser import RevisionBrowser
+        
+        revb = RevisionBrowser(self._branch, self)
+        response = revb.run()
+        if response != gtk.RESPONSE_NONE:
+            revb.hide()
+        
+            if response == gtk.RESPONSE_OK:
+                if revb.selected_revno is not None:
+                    self._entry_revid.set_text(revb.selected_revid)
+            
+            revb.destroy()
+    
+    def _on_add_clicked(self, widget):
+        """ Add button clicked handler. """
+        if len(self._entry_name.get_text()) == 0:
+            error_dialog(_("No tag name specified"),
+                         _("You have to specify the tag's desired name."))
+            return
+        
+        if len(self._entry_revid.get_text()) == 0:
+            self.revid = self._branch.last_revision()
+        else:
+            self.revid = self._entry_revid.get_text()
+        
+        self.tagname = self._entry_name.get_text()
+        
+        self.response(gtk.RESPONSE_OK)



More information about the Pkg-bazaar-commits mailing list