#!/usr/bin/python
#
# SvnCLBrowse -- graphical Subversion changelist browser
#
# ====================================================================
#    Licensed to the Apache Software Foundation (ASF) under one
#    or more contributor license agreements.  See the NOTICE file
#    distributed with this work for additional information
#    regarding copyright ownership.  The ASF licenses this file
#    to you under the Apache License, Version 2.0 (the
#    "License"); you may not use this file except in compliance
#    with the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing,
#    software distributed under the License is distributed on an
#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#    KIND, either express or implied.  See the License for the
#    specific language governing permissions and limitations
#    under the License.
# ====================================================================

# This script requires Python 2.5

import sys
import os
import getopt

# Try to import the wxWidgets modules.
try:
  import wx
  import wx.xrc
except ImportError:
  sys.stderr.write("""
ERROR: This program requires the wxWidgets Python bindings, which you
       do not appear to have installed.

""")
  raise

# Try to import the Subversion modules.
try:
  import svn.client, svn.wc, svn.core
except ImportError:
  sys.stderr.write("""
ERROR: This program requires the Subversion Python bindings, which you
       do not appear to have installed.

""")
  raise

status_code_map = {
  svn.wc.status_none        : ' ',
  svn.wc.status_normal      : ' ',
  svn.wc.status_added       : 'A',
  svn.wc.status_missing     : '!',
  svn.wc.status_incomplete  : '!',
  svn.wc.status_deleted     : 'D',
  svn.wc.status_replaced    : 'R',
  svn.wc.status_modified    : 'M',
  svn.wc.status_merged      : 'G',
  svn.wc.status_conflicted  : 'C',
  svn.wc.status_obstructed  : '~',
  svn.wc.status_ignored     : 'I',
  svn.wc.status_external    : 'X',
  svn.wc.status_unversioned : '?',
  }

def output_info(path, info, window):
  window.AppendText("Path: %s\n" % os.path.normpath(path))
  if info.kind != svn.core.svn_node_dir:
    window.AppendText("Name: %s\n" % os.path.basename(path))
  if info.URL:
    window.AppendText("URL: %s\n" % info.URL)
  if info.repos_root_URL:
    window.AppendText("Repository Root: %s\n" % info.repos_root_URL)
  if info.repos_UUID:
    window.AppendText("Repository UUID: %s\n" % info.repos_UUID)
  if info.rev >= 0:
    window.AppendText("Revision: %ld\n" % info.rev)
  if info.kind == svn.core.svn_node_file:
    window.AppendText("Node Kind: file\n")
  elif info.kind == svn.core.svn_node_dir:
    window.AppendText("Node Kind: directory\n")
  elif info.kind == svn.core.svn_node_none:
    window.AppendText("Node Kind: none\n")
  else:
    window.AppendText("Node Kind: unknown\n")
  if info.has_wc_info:
    if info.schedule == svn.wc.schedule_normal:
      window.AppendText("Schedule: normal\n")
    elif info.schedule == svn.wc.schedule_add:
      window.AppendText("Schedule: add\n")
    elif info.schedule == svn.wc.schedule_delete:
      window.AppendText("Schedule: delete\n")
    elif info.schedule == svn.wc.schedule_replace:
      window.AppendText("Schedule: replace\n")
    if info.depth == svn.core.svn_depth_unknown:
      pass
    elif info.depth == svn.core.svn_depth_empty:
      window.AppendText("Depth: empty\n")
    elif info.depth == svn.core.svn_depth_files:
      window.AppendText("Depth: files\n")
    elif info.depth == svn.core.svn_depth_immediates:
      window.AppendText("Depth: immediates\n")
    elif info.depth == svn.core.svn_depth_infinity:
      pass
    else:
      window.AppendText("Depth: INVALID\n")
    if info.copyfrom_url:
      window.AppendText("Copied From URL: %s\n" % info.copyfrom_url)
    if info.copyfrom_rev >= 0:
      window.AppendText("Copied From Rev: %ld\n" % info.copyfrom_rev)
  if info.last_changed_author:
    window.AppendText("Last Changed Author: %s\n" % info.last_changed_author)
  if info.last_changed_rev >= 0:
    window.AppendText("Last Changed Rev: %ld\n" % info.last_changed_rev)
  if info.last_changed_date:
    window.AppendText("Last Changed Date: %s\n" %
                      svn.core.svn_time_to_human_cstring(info.last_changed_date))
  if info.has_wc_info:
    if info.text_time:
      window.AppendText("Text Last Updated: %s\n" %
                        svn.core.svn_time_to_human_cstring(info.text_time))
    if info.prop_time:
      window.AppendText("Properties Last Updated: %s\n" %
                        svn.core.svn_time_to_human_cstring(info.prop_time))
    if info.checksum:
      window.AppendText("Checksum: %s\n" % info.checksum)
    if info.conflict_old:
      window.AppendText("Conflict Previous Base File: %s\n" % info.conflict_old)
    if info.conflict_wrk:
      window.AppendText("Conflict Previous Working File: %s\n" % info.conflict_wrk)
    if info.conflict_new:
      window.AppendText("Conflict Current Base File: %s\n" % info.conflict_new)
    if info.prejfile:
      window.AppendText("Conflict Properties File: %s\n" % info.prejfile)
  if info.lock:
    if info.lock.token:
      window.AppendText("Lock Token: %s\n" % info.lock.token)
    if info.lock.owner:
      window.AppendText("Lock Owner: %s\n" % info.lock.owner)
    if info.lock.creation_date:
      window.AppendText("Lock Created: %s\n" %
                        svn.core.svn_time_to_human_cstring(info.lock.creation_date))
    if info.lock.expiration_date:
      window.AppendText("Lock Expires: %s\n" %
                        svn.core.svn_time_to_human_cstring(info.lock.expiration_date))
    if info.lock.comment:
      num_lines = len(info.lock.comment.split("\n"))
      window.AppendText("Lock Comment (%d line%s): %s\n"
                        % (num_lines, num_lines > 1 and "s" or "", info.lock.comment))
  if info.changelist:
    window.AppendText("Changelist: %s\n" % info.changelist)
  window.AppendText("\n")

class _item:
  pass
  
class SvnCLBrowse(wx.App):
  def __init__(self, wc_dir):
    svn.core.svn_config_ensure(None)
    self.svn_ctx = svn.client.svn_client_create_context()
    self.svn_ctx.config = svn.core.svn_config_get_config(None)
    if wc_dir is not None:
      self.wc_dir = svn.core.svn_path_canonicalize(wc_dir)
    else:
      self.wc_dir = wc_dir
    wx.App.__init__(self)

  def OnInit(self):
    self.SetAppName("SvnCLBrowse")

    self.xrc = wx.xrc.EmptyXmlResource()
    wx.FileSystem.AddHandler(wx.MemoryFSHandler())
    wx.MemoryFSHandler.AddFile('XRC/SvnCLBrowse.xrc', _XML_RESOURCE)
    self.xrc.Load('memory:XRC/SvnCLBrowse.xrc')

    # XML Resource stuff.
    self.resources = _item()
    self.resources.CLBFrame = self.xrc.LoadFrame(None, 'CLBFrame')
    self.resources.CLBMenuBar = self.xrc.LoadMenuBar('CLBMenuBar')
    self.resources.CLBMenuFileQuit = self.xrc.GetXRCID('CLBMenuFileQuit')
    self.resources.CLBMenuOpsInfo = self.xrc.GetXRCID('CLBMenuOpsInfo')
    self.resources.CLBMenuOpsMembers = self.xrc.GetXRCID('CLBMenuOpsMembers')
    self.resources.CLBMenuHelpAbout = self.xrc.GetXRCID('CLBMenuHelpAbout')
    self.resources.CLBDirNav = self.resources.CLBFrame.FindWindowById(
      self.xrc.GetXRCID('CLBDirNav'))
    self.resources.CLBChangelists = self.resources.CLBFrame.FindWindowById(
      self.xrc.GetXRCID('CLBChangelists'))
    self.resources.CLBVertSplitter = self.resources.CLBFrame.FindWindowById(
      self.xrc.GetXRCID('CLBVertSplitter'))
    self.resources.CLBHorzSplitter = self.resources.CLBFrame.FindWindowById(
      self.xrc.GetXRCID('CLBHorzSplitter'))
    self.resources.CLBOutput = self.resources.CLBFrame.FindWindowById(
      self.xrc.GetXRCID('CLBOutput'))
    self.resources.CLBStatusBar = self.resources.CLBFrame.CreateStatusBar(2)
    
    # Glue some of our extra stuff onto the main frame.
    self.resources.CLBFrame.SetMenuBar(self.resources.CLBMenuBar)
    self.resources.CLBStatusBar.SetStatusWidths([-1, 100])
    
    # Event handlers.  They are the key to the world.
    wx.EVT_CLOSE(self.resources.CLBFrame, self._FrameClosure)
    wx.EVT_MENU(self, self.resources.CLBMenuFileQuit, self._FileQuitMenu)
    wx.EVT_MENU(self, self.resources.CLBMenuOpsInfo, self._OpsInfoMenu)
    wx.EVT_MENU(self, self.resources.CLBMenuOpsMembers, self._OpsMembersMenu)
    wx.EVT_MENU(self, self.resources.CLBMenuHelpAbout, self._HelpAboutMenu)
    wx.EVT_TREE_ITEM_ACTIVATED(self, self.resources.CLBDirNav.GetTreeCtrl().Id,
                               self._DirNavSelChanged)

    # Reset our working directory
    self._SetWorkingDirectory(self.wc_dir)
    
    # Resize and display our frame.
    self.resources.CLBFrame.SetSize(wx.Size(600, 400))
    self.resources.CLBFrame.Center()
    self.resources.CLBFrame.Show(True)
    self.resources.CLBVertSplitter.SetSashPosition(
      self.resources.CLBVertSplitter.GetSize()[0] / 2)
    self.resources.CLBHorzSplitter.SetSashPosition(
      self.resources.CLBHorzSplitter.GetSize()[1] / 2)

    # Tell wxWidgets that this is our main window
    self.SetTopWindow(self.resources.CLBFrame)

    # Return a success flag
    return True

  def _SetWorkingDirectory(self, wc_dir):
    if wc_dir is None:
      return
    if not os.path.isdir(wc_dir):
      wc_dir = os.path.abspath('/')
    self.wc_dir = os.path.abspath(wc_dir)
    self.resources.CLBChangelists.Clear()
    self.resources.CLBDirNav.SetPath(self.wc_dir)
    self.resources.CLBFrame.SetTitle("SvnCLBrowse - %s" % (self.wc_dir))
    changelists = {}
    self.resources.CLBFrame.SetStatusText("Checking '%s' for status..." \
                                         % (self.wc_dir))
    wx.BeginBusyCursor()
    
    def _status_callback(path, status, clists=changelists):
      if status.entry and status.entry.changelist:
        clists[status.entry.changelist] = None
        
    # Do the status crawl, using _status_callback() as our callback function.
    revision = svn.core.svn_opt_revision_t()
    revision.type = svn.core.svn_opt_revision_head
    try:
      svn.client.status2(self.wc_dir, revision, _status_callback,
                         svn.core.svn_depth_infinity,
                         False, False, False, True, self.svn_ctx)
    except svn.core.SubversionException:
      self.resources.CLBStatusBar.SetStatusText("UNVERSIONED", 2)
    else:
      changelist_names = changelists.keys()
      changelist_names.sort()
      for changelist in changelist_names:
        self.resources.CLBChangelists.Append(changelist)
    finally:
      wx.EndBusyCursor()
      self.resources.CLBFrame.SetStatusText("")

  def _Destroy(self):
    self.resources.CLBFrame.Destroy()
    
  def _DirNavSelChanged(self, event):
    self._SetWorkingDirectory(self.resources.CLBDirNav.GetPath())

  def _GetSelectedChangelists(self):
    changelists = []
    items = self.resources.CLBChangelists.GetSelections()
    for item in items:
      changelists.append(str(self.resources.CLBChangelists.GetString(item)))
    return changelists

  def _OpsMembersMenu(self, event):
    self.resources.CLBOutput.Clear()
    changelists = self._GetSelectedChangelists()
    if not changelists:
      return

    def _info_receiver(path, info, pool):
      self.resources.CLBOutput.AppendText("   %s\n" % (path))

    for changelist in changelists:
      self.resources.CLBOutput.AppendText("Changelist: %s\n" % (changelist))
      revision = svn.core.svn_opt_revision_t()
      revision.type = svn.core.svn_opt_revision_working
      svn.client.info2(self.wc_dir, revision, revision,
                       _info_receiver, svn.core.svn_depth_infinity,
                       [changelist], self.svn_ctx)
      self.resources.CLBOutput.AppendText("\n")
  
  def _OpsInfoMenu(self, event):
    self.resources.CLBOutput.Clear()
    changelists = self._GetSelectedChangelists()
    if not changelists:
      return

    def _info_receiver(path, info, pool):
      output_info(path, info, self.resources.CLBOutput)
    
    revision = svn.core.svn_opt_revision_t()
    revision.type = svn.core.svn_opt_revision_working
    svn.client.info2(self.wc_dir, revision, revision,
                     _info_receiver, svn.core.svn_depth_infinity,
                     changelists, self.svn_ctx)
    
  def _FrameClosure(self, event):
    self._Destroy()

  def _FileQuitMenu(self, event):
    self._Destroy()
    
  def _HelpAboutMenu(self, event):
    wx.MessageBox("SvnCLBrowse"
                  " -- graphical Subversion changelist browser.\n\n",
                  "About SvnCLBrowse",
                  wx.OK | wx.CENTER,
                  self.resources.CLBFrame)

  def OnExit(self):
    pass


_XML_RESOURCE = """<?xml version="1.0" ?>
<resource>
  <object class="wxMenuBar" name="CLBMenuBar">
    <object class="wxMenu">
      <label>&amp;File</label>
      <object class="wxMenuItem" name="CLBMenuFileQuit">
        <label>&amp;Quit</label>
        <accel>CTRL+Q</accel>
        <help>Quit SvnCLBrowse.</help>
      </object>
    </object>
    <object class="wxMenu">
      <label>&amp;Subversion</label>
      <object class="wxMenuItem" name="CLBMenuOpsInfo">
        <label>&amp;Info</label>
        <help>Show information about members of the selected changelist(s).</help>
      </object>
      <object class="wxMenuItem" name="CLBMenuOpsMembers">
        <label>&amp;Members</label>
        <help>List the members of the selected changelist(s).</help>
      </object>
    </object>
    <object class="wxMenu">
      <label>&amp;Help</label>
      <object class="wxMenuItem" name="CLBMenuHelpAbout">
        <label>&amp;About...</label>
        <help>About SvnCLBrowse.</help>
      </object>
    </object>
  </object>
  <object class="wxFrame" name="CLBFrame">
    <title>SvnCLBrowse -- graphical Subversion changelist browser</title>
    <centered>1</centered>
    <style>wxDEFAULT_FRAME_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER|wxRESIZE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxTAB_TRAVERSAL</style>
    <object class="wxFlexGridSizer">
      <cols>1</cols>
      <rows>1</rows>
      <object class="sizeritem">
        <object class="wxSplitterWindow" name="CLBVertSplitter">
          <object class="wxPanel">
            <object class="wxFlexGridSizer">
              <cols>1</cols>
              <rows>3</rows>
              <growablecols>0</growablecols>
              <growablerows>0</growablerows>
              <growablerows>1</growablerows>
              <growablerows>2</growablerows>
              <object class="sizeritem">
                <object class="wxSplitterWindow" name="CLBHorzSplitter">
                  <orientation>horizontal</orientation>
                  <sashpos>200</sashpos>
                  <minsize>50</minsize>
                  <style>wxSP_NOBORDER|wxSP_LIVE_UPDATE</style>
                  <object class="wxPanel">
                    <object class="wxStaticBoxSizer">
                      <label>Local Modifications</label>
                      <orient>wxHORIZONTAL</orient>
                      <object class="sizeritem">
                        <object class="wxGenericDirCtrl" name="CLBDirNav">
                          <style>wxDIRCTRL_DIR_ONLY</style>
                        </object>
                        <flag>wxEXPAND</flag>
                        <option>1</option>
                      </object>
                    </object>
                  </object>
                  <object class="wxPanel">
                    <object class="wxStaticBoxSizer">
                      <label>Changelists</label>
                      <orient>wxHORIZONTAL</orient>
                      <object class="sizeritem">
                        <object class="wxListBox" name="CLBChangelists">
                          <content>
                            <item/></content>
                          <style>wxLB_MULTIPLE</style>
                        </object>
                        <option>1</option>
                        <flag>wxALL|wxEXPAND</flag>
                      </object>
                    </object>
                  </object>
                </object>
                <flag>wxEXPAND</flag>
                <option>1</option>
              </object>
            </object>
          </object>
          <object class="wxPanel">
            <object class="wxFlexGridSizer">
              <cols>1</cols>
              <object class="sizeritem">
                <object class="wxStaticBoxSizer">
                  <label>Output</label>
                  <orient>wxVERTICAL</orient>
                  <object class="sizeritem">
                    <object class="wxTextCtrl" name="CLBOutput">
                      <style>wxTE_MULTILINE|wxTE_READONLY|wxTE_LEFT|wxTE_DONTWRAP</style>
                    </object>
                    <option>1</option>
                    <flag>wxEXPAND</flag>
                  </object>
                </object>
                <option>1</option>
                <flag>wxALL|wxEXPAND</flag>
                <border>5</border>
              </object>
              <rows>1</rows>
              <growablecols>0</growablecols>
              <growablerows>0</growablerows>
            </object>
          </object>
          <orientation>vertical</orientation>
          <sashpos>130</sashpos>
          <minsize>50</minsize>
          <style>wxSP_NOBORDER|wxSP_LIVE_UPDATE</style>
        </object>
        <option>1</option>
        <flag>wxEXPAND</flag>
      </object>
      <growablecols>0</growablecols>
      <growablerows>0</growablerows>
    </object>
  </object>
</resource>
"""

def usage_and_exit(errmsg=None):
  stream = errmsg and sys.stderr or sys.stdout
  progname = os.path.basename(sys.argv[0])
  stream.write("""%s -- graphical Subversion changelist browser
  
Usage: %s [DIRECTORY]

Launch the SvnCLBrowse graphical changelist browser, using DIRECTORY
(or the current working directory, if DIRECTORY is not provided) as
the initial browse location.

""" % (progname, progname))
  if errmsg:
    stream.write("ERROR: %s\n" % (errmsg))
  sys.exit(errmsg and 1 or 0)
  
def main():
  opts, args = getopt.gnu_getopt(sys.argv[1:], 'h?', ['help'])
  for name, value in opts:
    if name == '-h' or name == '-?' or name == '--help':
      usage_and_exit()
  argc = len(args)
  if argc == 0:
    wc_dir = '.'
  elif argc == 1:
    wc_dir = sys.argv[1]
  else:
    usage_and_exit("Too many arguments")
  app = SvnCLBrowse(wc_dir)
  app.MainLoop()
  app.OnExit()

if __name__ == "__main__":
  main()
