#!/usr/bin/env python
# GUI for MPM (MiKTeX Package Manager by Christian Schenk) program

_ = lambda x : x

import sys

try: 
  import pygtk 
  pygtk.require("2.0") 
except: 
  pass 
try: 
  import os
  import gobject
  import gtk 
  import pango
except ImportError, e:
  print 'standard modules missing', e
  sys.exit(1)


try:
  import helper
  import libglade
  from infopack import InfoDialog
  from ..pympm import MiKTeX_config, MiKTeX_Distrib
  from ..constants import APP_NAME, CONFIG_LOCATION

except ImportError, e:
  print 'MISSING OWN MODULES',e
  sys.exit(1)

UPDATE= 2
INSTALL=1
UNINSTALL=0
#####################################################################   
#####################################################################
#####################################################################   
def average_colors(c1, c2):
  """
  Average two color given as textual strings (hex).
  TODO: Must be a much better way of implementing this!!!
  """
  s=str(hex((int(c1[1:],16) + int(c2[1:],16))/2))[2:]
  if s[-1] == 'L':
    s=s[:-1]
  return '#'+s.zfill(12)

def set_model_from_list (cb, items):
  """Setup a ComboBox or ComboBoxEntry based on a list of strings."""           
  model = gtk.ListStore(str)
  for i in items:
    model.append([i])
  cb.set_model(model)
  if type(cb) == gtk.ComboBoxEntry and cb.get_text_column() == -1:
    cb.set_text_column(0)
    # For some reason these lines are messing things up
#   elif type(cb) == gtk.ComboBox:
#     cell = gtk.CellRendererText()
#     cb.pack_start(cell, True)
#     cb.add_attribute(cell, 'text', 0)

def is_local_repository(repo):
  return os.path.exists(repo) and os.path.isdir(repo)


def is_remote_repository(repo):
  return not is_local_repository(repo)


          #####################################################################
          #####################################################################
                       # FUNCTIONS TO MANAGE THE PREFERENCES DIALOG
          #####################################################################
          #####################################################################   
class PrefDialog(libglade.GladeWrapper):
  def __init__(self, Filename, conf):
    """ Creates the preferences dialog.
        Filename is where the glade file lives
        conf is a MiKTeX_conf (configuration) object
    """
    libglade.GladeWrapper.__init__(self, Filename, "prefdialog")

    self.modified={}
    self.config= conf
    self.config_gui= self.config.full_conf['gui']

    self.set_page_repo()
    self.set_page_net()
    self.set_page_prog()

    response= self.prefdialog.run()
    if response != gtk.RESPONSE_OK:
      self.modified= {}

    self.prefdialog.destroy()

  def set_page_repo(self):
    """ Set values for the repository list to show and the last chosen  """
    # Set repository list
    repository=self.config.get_attribute('repository')

    if self.config.get_attribute('repository_type'):
      if self.config.get_attribute('repository_type').lower()[0]=='l':
        self.fclocal.set_current_folder(self.config.get_attribute('repository'))
        self.rblocal.set_active(0)
        self.on_rblocal_toggled(self.rblocal)
      else:
        self.rbremote.set_active(1)
        self.on_rbremote_toggled(self.rbremote)
        try:
          n= self.config.repositories.index(repository.strip())
        except:
          n=0
        self.cbremote.set_active(n)
    
    self.fcroot.set_current_folder(self.config.get_attribute('root'))

  def set_page_prog(self):
    if self.config_gui['font_info']:
      self.cbfont1.set_active(True)
      self.bfont1.set_property('sensitive',True)
      self.bfont1.set_font_name(self.config_gui['font_info'])
    else:
      self.bfont1.set_property('sensitive',False)      

    if self.config_gui['font_list']:
      self.cbfont2.set_active(True)
      self.bfont2.set_property('sensitive',True)
      self.bfont2.set_font_name(self.config_gui['font_list'])
    else:
      self.bfont2.set_property('sensitive',False)      

    self.cbsave_settings.set_active(self.config_gui['save_on_exit'])

    k= 'install_color'
    if self.config_gui.has_key(k) and self.config_gui[k]:
      self.colbadd.set_color(gtk.gdk.color_parse(self.config_gui[k]))
    k= 'remove_color'
    if self.config_gui.has_key(k) and self.config_gui[k]:
      self.colbrem.set_color(gtk.gdk.color_parse(self.config_gui[k]))

  def set_page_net(self):
    """ Set values for the install-root and network proxy  """
    http_proxy= self.config.get_attribute('http_proxy')
    ftp_proxy= self.config.get_attribute('ftp_proxy')
    no_proxy= self.config.get_attribute('no_proxy')
    all_proxy= self.config.get_attribute('all_proxy')

    if http_proxy or ftp_proxy or all_proxy:
      self.rbmanual.set_active(True)
      self.on_rbmanual_toggled(self.rbmanual)
      if http_proxy:
        host=http_proxy.split(':')
        lh= len(host)-1
        s=""
        for i in range(lh):
          s += host[i]
        self.ehttp_host.set_text(s)
        self.sphttp_port.set_value(int(host[lh]))
      if http_proxy == ftp_proxy == all_proxy:
        self.cbsame_proxy.set_active()
        self.on_same_proxy_toggled()  #OJO ACA
      else:
        if ftp_proxy:
          host= ftp_proxy.split(':')
          lh= len(host)-1
          s=""
          for i in range(lh):
            s += host[i]
          self.eftp_host.set_text(s)
          self.spftp_port.set_value(int(host[lh]))
        if all_proxy:
          host= all_proxy.split(':')
          lh= len(host)-1
          s=""
          for i in range(lh):
            s += host[i]
          self.eall_host.set_text(s)
          self.spall_port.set_value(int(host[lh]))
      if no_proxy:
        self.enoproxy.set_text(no_proxy)
    else:
      self.rbdirect.set_active(True)
      self.on_rbdirect_toggled(self.rbdirect)

  def on_font_toggled(self, widget):
    state= widget.get_active()
    if widget.get_name() == 'cbfont1':
      self.bfont1.set_property('sensitive',state)
    elif widget.get_name() == 'cbfont2':
      self.bfont2.set_property('sensitive',state)

  def on_same_proxy_toggled(self, widget):
    state= not self.cbsame_proxy.get_active()
    self.lftp.set_property('sensitive',state)
    self.lall.set_property('sensitive',state)
    self.lftp_port.set_property('sensitive',state)
    self.lall_port.set_property('sensitive',state)
    self.eftp_host.set_property('sensitive',state)
    self.eall_host.set_property('sensitive',state)
    self.spftp_port.set_property('sensitive',state)
    self.spall_port.set_property('sensitive',state)

  def on_rbmanual_toggled(self,widget):
    self.manual_box.set_property('sensitive',True)
    self.cbsame_proxy.set_property('sensitive',True)

  def on_rbdirect_toggled(self,widget):
    self.manual_box.set_property('sensitive',False)
    self.cbsame_proxy.set_property('sensitive',False)

  def on_rblocal_toggled(self,widget):
    self.fclocal.set_current_folder(self.config.get_attribute('repository'))
    self.fclocal.set_property('sensitive',True)
    self.bupdaterepo.set_property('sensitive',False)
    self.cbremote.set_property('sensitive',False)

  def on_rbremote_toggled(self,widget):
    self.fclocal.set_property('sensitive',False)
    lista=[]
    for r in self.config.repositories:
      r= r.strip()
      if is_remote_repository(r):
        lista.append(r.strip("'"))
    set_model_from_list(self.cbremote, lista)
    self.bupdaterepo.set_property('sensitive',True)
    self.cbremote.set_property('sensitive',True)
    self.cbremote.set_active(0)

  def on_bupdaterepo_clicked(self, widget):
    print 'Updating repositories database'
    self.config.update_repositories()  # Updates and Writes to self.config.repositories
    lista=[]
    for r in self.config.repositories:
      lista.append(r.strip("'"))
    set_model_from_list(self.cbremote, lista)
    self.cbremote.set_active(0)

  def on_bprefapply_clicked(self, widget):
    """ When apply is clicked, all values selected in the window are taken and
        stored in self.config
    """
    self.get_page_repo()
    self.get_page_net()
    self.get_page_prog()


  def get_page_repo(self):
    if self.rblocal.get_active():
      repo= self.fclocal.get_current_folder()
      repotype='Local'
    else:
      repo= self.cbremote.get_active_text()
      repotype='Remote'

    if repo != self.config.get_attribute('repository'):
      self.modified['repository']=repo
      self.modified['repository_type']=repotype

    self.modified['repositories']= self.config.repositories
    root=self.fcroot.get_current_folder()
    if root != self.config.get_attribute('root'):
      self.modified['root']=root

  def get_page_prog(self):
    if self.bfont1.get_property('sensitive'):
      if self.config_gui['font_info'] != self.bfont1.get_font_name():
        self.modified['font_info']= self.bfont1.get_font_name()
    else:
      if self.config_gui['font_info']:
        self.modified['font_info']= None

    if self.bfont2.get_property('sensitive'):
      if self.config_gui['font_list'] != self.bfont2.get_font_name():
        self.modified['font_list']= self.bfont2.get_font_name()
    else:
      if self.config_gui['font_list']:
        self.modified['font_list']= None

    if  self.config_gui['save_on_exit'] != self.cbsave_settings.get_active():
      self.modified['save_on_exit']= self.cbsave_settings.get_active()

    k='install_color'
    if self.config_gui.has_key(k) and self.config_gui[k] != self.colbadd.get_color():
      self.modified[k]= self.colbadd.get_color().to_string()


    k='remove_color'
    if self.config_gui.has_key(k) and self.config_gui[k] != self.colbadd.get_color():
      self.modified[k]= self.colbrem.get_color().to_string()

  def get_page_net(self):
    proxies= ['http_proxy','ftp_proxy','all_proxy']
    if self.rbdirect.get_active():
      for p in proxies:  # Set all proxies to None
        self.config.set_attribute(p, None)
    else:
      if self.ehttp_host.get_property('sensitive'):
        host= self.ehttp_host.get_text().strip()
        if host != "":
          host +=  ':' + str(self.sphttp_port.get_value_as_int())
          self.config.set_attribute(proxies[0],host)
        else:
          self.config.set_attribute(proxies[0],None)

      if self.cbsame_proxy.get_active():
        for p in proxies[1:2]:
          self.config.set_attribute(p,host)          
      else:

        host= self.eftp_host.get_text().strip()
        if host != "":
          host +=  ':' + str(self.spftp_port.get_value_as_int())
          self.config.set_attribute(proxies[1],host)
        else:
          self.config.set_attribute(proxies[1],None)

        host= self.eall_host.get_text().strip()
        if host != "":
          host +=  ':' + str(self.spall_port.get_value_as_int())
          self.config.set_attribute(proxies[2],host)
        else:
          self.config.set_attribute(proxies[2],None)

      host= self.enoproxy.get_text().strip()
      self.config.set_attribute('no_proxy',host)
        

  def on_bprefclose_clicked(self, widget):
    self.prefdialog.destroy()


#####################################################################
#####################################################################   
#####################################################################
#####################################################################   

# #####################################################################   
# #####################################################################
# #####################################################################   
class PackTree(libglade.GladeWrapper):
#   #Here are some variables that can be reused later
  Columns=[ "Package", # Not used
    "i",
    "Name",
    "# Files",
    "Size (kb)",
    "Install date",
    "Short description"
    ]

  (COL_PACK, COL_STATE, COL_NAME, COL_NFILES, COL_SIZE, COL_INSTIME, COL_TITLE, COL_VISIBLE, COL_PENDING
   , COL_COLOR
   )= range(10)

  Options={}
  Options['search_column']= COL_NAME
  infodialog= None
  message= ""
  pending_oper={}

  def __init__(self, Filename):
    """This class is used to show the list of electrons attached to a nucleus"""
    self.gladeFile= Filename

    libglade.GladeWrapper.__init__(self, Filename, 'scrolledw1')

    # Create the listStore Model to use with the electronView
    self.packList = gtk.ListStore(gobject.TYPE_PYOBJECT
                                , gobject.TYPE_BOOLEAN  #Installed?
                                , gobject.TYPE_STRING   #Name
                                , gobject.TYPE_UINT   #number of files
                                , gobject.TYPE_UINT  #size
                                , gobject.TYPE_STRING  #Installation-time
                                , gobject.TYPE_STRING  #title
                                , gobject.TYPE_BOOLEAN  #Visible?
                                , gobject.TYPE_BOOLEAN  #pending?
                                , gobject.TYPE_STRING  #Color pending
                             )

#     self.restricted= False  # Used to keep track if the view is complete or not

    # Creation of the filter, from the model
    self.filter = self.packList.filter_new()
    self.filter.set_visible_column(self.COL_VISIBLE)

    # Attatch the model "packList" to the treeView "TreeView" from glade file
    self.TreeView.set_model(self.packList)   

    #Add all of the List Columns to the View
    self.__add_columns(self.TreeView)

    self.colores= ['#0000ffff0000', '#ffff0000bbbb', 'blue']
    self.colores[UPDATE]= average_colors(self.colores[INSTALL], self.colores[UNINSTALL])


  def __add_columns(self, treeview):
    model = treeview.get_model()

    # column for install/uninstall toggles
    renderer = gtk.CellRendererToggle()
    renderer.connect('toggled', self.install_toggled, model)
    column = gtk.TreeViewColumn(self.Columns[self.COL_STATE], renderer, active=self.COL_STATE, cell_background=self.COL_COLOR)
    column.set_sort_column_id(self.COL_STATE)

    treeview.append_column(column)
    
    # column for package name
    renderer= gtk.CellRendererText()
    column = gtk.TreeViewColumn(self.Columns[self.COL_NAME],renderer, text=self.COL_NAME, background=self.COL_COLOR)
    column.set_sort_column_id(self.COL_NAME)
    column.set_reorderable(True)


 
    treeview.append_column(column)
    
    # column for number of files
    renderer= gtk.CellRendererText()
    renderer.set_property('xalign',1)

    column = gtk.TreeViewColumn(self.Columns[self.COL_NFILES],renderer, text=self.COL_NFILES, background=self.COL_COLOR)
    column.set_sort_column_id(self.COL_NFILES)
    column.set_reorderable(True)

    treeview.append_column(column)
    
    # column for Size of files
    column = gtk.TreeViewColumn(self.Columns[self.COL_SIZE], renderer, text=self.COL_SIZE)
    column.set_sort_column_id(self.COL_SIZE)
    column.set_reorderable(True)
    treeview.append_column(column)

    # column for Installation time
    column = gtk.TreeViewColumn(self.Columns[self.COL_INSTIME], gtk.CellRendererText(), text=self.COL_INSTIME, background=self.COL_COLOR)
    column.set_sort_column_id(self.COL_INSTIME)
    column.set_reorderable(True)
    treeview.append_column(column)

      # column for title
    column = gtk.TreeViewColumn(self.Columns[self.COL_TITLE], gtk.CellRendererText(), text=self.COL_TITLE, background=self.COL_COLOR)
    column.set_sort_column_id(self.COL_TITLE)
    column.set_reorderable(True)
    treeview.append_column(column)


  def ini(self,distribution):
    # Add packages from distribution to List 
    self.add_packages(distribution)


  def set_colors(self, addc= None, remc= None):
    self.oldinscolor=self.colores[INSTALL]
    self.olduninscolor=self.colores[UNINSTALL]
    if addc == None:
      addc= self.colores[INSTALL]
    if remc == None:
      remc= self.colores[UNINSTALL]
    self.colores[INSTALL]= addc
    self.colores[UNINSTALL]= remc
    self.colores[UPDATE]= average_colors(addc,remc)
    pending= self.pending_oper.keys()
    for row in self.packList:
      if row[self.COL_NAME] in pending:
        if row[self.COL_COLOR] != None:
          if row[self.COL_COLOR]== self.oldinscolor:
            row[self.COL_COLOR]= self.colores[INSTALL]
          elif row[self.COL_COLOR]== self.olduninscolor:
            row[self.COL_COLOR]= self.colores[UNINSTALL]
          else:
            row[self.COL_COLOR]= self.colores[UPDATE]



  def updatelist(self, newfont):
    self.fontlist= newfont
    self.TreeView.modify_font(newfont)

  def updateinfo(self, newfont):
    self.fontinfo= newfont
    if self.infodialog:
      self.infodialog.set_fonts(newfont)


  def add_packages(self, distribution):
    self.distrib= distribution
    model = self.packList

    # Performance tip: No updating while storing lot of data
    self.TreeView.freeze_child_notify() 
    self.TreeView.set_model(None)

    for p in distribution.list_packs():
      model.append(p.get_values()[0:7]+(True,False,None))
    # Performance tip: Restoring normal updating
    self.TreeView.set_model(model)
    self.TreeView.thaw_child_notify()

    # Search Column must be set here. Otherwise gets overwritten
    self.TreeView.set_search_column(self.Options['search_column'])


  def install_toggled(self, cell, path, model):
    """ Toggles the installation state column of the package and qeues it for
    installing or uninstalling it.
    """
    filter_iter = self.filter.get_iter((int(path),))
    iter=self.filter.convert_iter_to_child_iter(filter_iter)
    pack= model.get_value(iter, self.COL_PACK)
    inst= pack.is_installed()

    state= self.add_to_install_queue(pack)
    model.set_value(iter, self.COL_PENDING, state!= None)

    if state == None:
      model.set_value(iter, self.COL_COLOR, None)
      model.set_value(iter,self.COL_STATE, inst)
    else:
      model.set_value(iter, self.COL_COLOR, self.colores[state])
      model.set_value(iter,self.COL_STATE, state != UNINSTALL )


  def add_to_install_queue(self, pack):
    name= pack.get_property('name')
    inst= pack.is_installed()
    upd= pack.is_updatable()
    pending= name in self.pending_oper.keys()
    message= "Package "+ pack.get_property('name')


    if inst:
      if upd:
        if pending:
          if self.pending_oper[name] == UPDATE:
            self.pending_oper[name]= UNINSTALL
            message+= " queued for uninstallation."
          else:
            del self.pending_oper[name]
            message+= " unqueued."
        else:
          self.pending_oper[name]= UPDATE
          message+= " queued for update."
      else:
        if pending:
          del self.pending_oper[name]
          message+= " unqeued."
        else:
          self.pending_oper[name]= UNINSTALL
          message+= " qeued for uninstallation."
    else:
      if pending:
        del self.pending_oper[name]
        message+= " unqeued."
      else:
        self.pending_oper[name]= INSTALL
        message+= " qeued for installation."

    self.TreeView.emit("mensaje", message)
    if self.pending_oper.has_key(name):
      return self.pending_oper[name]
    else:
      return None


  def popup(self, widget, event):
    libglade.GladeWrapper.__init__(self, self.gladeFile, "popup_pack")
    self.popup_pack.popup(None, None, None, event.button, event.time)



  def on_poppackhelp_activate(self, event):
    selection= self.TreeView.get_selection()
    model,iter = selection.get_selected()

    if iter:
      if self.is_filter():  # Convert to child (packList)
        iter=self.filter.convert_iter_to_child_iter(iter)
        model=self.packList
      pack= model.get_value(iter, self.COL_PACK)
      self.distrib.get_package_help(pack)

  def on_popupdate_activate(self, event):
    selection= self.TreeView.get_selection()
    model,iter = selection.get_selected()

    if iter:
      if self.is_filter():  # Convert to child (packList)
        iter=self.filter.convert_iter_to_child_iter(iter)
        model=self.packList

      pack = model.get_value(iter, self.COL_PACK)
      self.distrib.update_package(pack)

  def on_popadd_activate(self, event):
    selection= self.TreeView.get_selection()
    model,iter = selection.get_selected()

    if iter:
      if self.is_filter():  # Convert to child (packList)
        iter= self.filter.convert_iter_to_child_iter(iter)
        model=self.packList

      pack = model.get_value(iter, self.COL_PACK)
      inst= pack.is_installed()

      state= self.add_to_install_queue(pack)
      model.set_value(iter, self.COL_PENDING, state)
      if state:
        if not inst:
          model.set_value(iter, self.COL_COLOR,  self.colores[INSTALL])
        else:
          model.set_value(iter, self.COL_COLOR,  self.colores[UNINSTALL])
      else:
        model.set_value(iter, self.COL_COLOR, None)

      model.set_value(iter,self.COL_STATE, not model.get_value(iter, self.COL_STATE))


  def on_popinfo_activate(self, event):
    selection= self.TreeView.get_selection()
    model,iter = selection.get_selected()

    if self.is_filter():  
      iter=self.filter.convert_iter_to_child_iter(iter) # Convert to child (packList)
      model=self.packList  
    if iter:
      path = model.get_path(iter)[0]
      cell = self.TreeView.get_column(0).get_cell_renderers()[0]
      self.get_info(model[path])

  def on_TreeView_cursor_changed(self, event):
    """ Show info if window is visible """
    try:
      if self.infodialog1.get_property("visible"):
        self.on_popinfo_activate(event)
    except:
      pass

  def get_info(self, row):
    if not self.infodialog:
      self.infodialog= InfoDialog(self.gladeFile)
      self.infodialog.set_fonts(self.fontinfo)
      self.infodialog1= self.infodialog.infodialog1

    pack=row[self.COL_PACK]
    self.infodialog.show_pack_info(pack, self.distrib.conf)
  
  def on_TreeView_button_press_event(self, treeview, event):
    if event.button == 3:
      x = int(event.x)
      y = int(event.y)
      time = event.time
      pthinfo = treeview.get_path_at_pos(x, y)
      if pthinfo is not None:
        path, col, cellx, celly = pthinfo
        treeview.grab_focus()
        treeview.set_cursor( path, col, 0)
        self.popup(treeview, event)
      return 1
    
  def is_filter(self):
    return (self.TreeView.get_model() is self.filter)
    


class gMPMwnd(libglade.GladeWrapper):
  """This class represents the gui main window"""
  programa=APP_NAME

# gobject.TYPE_BOOLEAN, (gtk.Button, gobject.TYPE_INT))

  # Default (Initialization) values
  data={}
  searchwords= []
  prefmodified=None  
  guisection='gui'
#   pending_operations={}

  def __init__(self, Filename, WindowName, start_dir="."):
    libglade.GladeWrapper.__init__(self, Filename, WindowName)

    self.findoptcb.set_property('active',0)

    self.gladeFile= Filename
    self.distrib= MiKTeX_Distrib()
    if self.distrib.dist == {}:
      helper.show_error_dlg(_('I could not find a valid MiKTeX distribution.\nIf you already have a MikTeX distribution, set correctly the ROOT directory in preferences.'))
#       helper.show_error_dlg(_('Current configuration not valid\nRun First with option: --update-db'))
#       sys.exit()

    # Override ask_pass_func
    self.distrib.ask_pass_func= helper.gui_ask_pass_func

    self.config= self.distrib.conf

    if not self.config.full_conf.has_key(self.guisection):
      self.config.full_conf[self.guisection]={}

    if not self.config.full_conf[self.guisection].has_key('save_on_exit'):
      self.config.full_conf[self.guisection]['save_on_exit']='Yes'

    self.config_gui= self.config.full_conf[self.guisection]
    self.process_options()


    self.TVpack= PackTree(self.gladeFile)
    self.TVpack.pending_oper={}

    gobject.signal_new("mensaje", gtk.TreeView,
                       gobject.SIGNAL_RUN_LAST,
                       gobject.TYPE_NONE
                       , (gobject.TYPE_STRING,))


    # Initialize the packages list
    self.TVpack.updatelist(pango.FontDescription(self.config_gui['font_list']))
    self.TVpack.updateinfo(pango.FontDescription(self.config_gui['font_info']))
    self.TVpack.set_colors(self.config_gui['install_color'],self.config_gui['remove_color'])

    if not self.config_gui['install_color']:
      self.config_gui['install_color']= self.TVpack.colores[INSTALL]
    if not self.config_gui['remove_color']:
      self.config_gui['remove_color']= self.TVpack.colores[UNINSTALL]

    self.TVpack.ini(self.distrib)
    self.vbpack.pack_end(self.TVpack.scrolledw1,True,True,10)

    self.context_id= self.stbar1.get_context_id("Package installed/removed")
    self.TVpack.TreeView.connect("mensaje", self.set_statusbar, self.context_id)

    if self.distrib.dist == {}:
      """Empty package list """
      mensaje= _("Package list is empty. You have to change the Root MiKTeX Directory to a valid location"
        + " or update the database.\nDo you want to update the database now?")
      response= helper.show_question_dlg(mensaje)
      if response == gtk.RESPONSE_YES:
        self.distrib.update_db()
      else:
        self.on_preferences_activate(self.tbprefs)
    else:
      npack= len(self.distrib.dist.keys())
      self.set_statusbar(msg= "Loaded "+str(npack)+" packages.")

    if self.config_gui['save_on_exit']:
      self.config.save_MiKTeX_config(self.config.inifiles[-1])


#     ############################################################
#     ######## Saving and Loading         ########################
#     ############################################################
  def process_options(self):
    """ Process gui options. Currrently only:
    save_on_exit
    font_info
    font_list
    """
    if self.config_gui.has_key('save_on_exit'):
      if self.config_gui['save_on_exit'].strip()[0].lower() in 'ty1':
        self.config_gui['save_on_exit']= True
      else:
        self.config_gui['save_on_exit'] = False
    else:
      self.config_gui['save_on_exit']= True

    if not self.config_gui.has_key('install_color') or self.config_gui['install_color']=='None':
      self.config_gui['install_color']= None

    if not self.config_gui.has_key('remove_color') or self.config_gui['remove_color']=='None':
      self.config_gui['remove_color']= None

    if not self.config_gui.has_key('font_info') or self.config_gui['font_info']=='None':
      self.config_gui['font_info']= None
    if not self.config_gui.has_key('font_list') or self.config_gui['font_list']=='None':
      self.config_gui['font_list']= None

      
  def reload_distrib(self):
    npack= self.distrib.refresh_list_packages()
    self.TVpack.packList.clear()
    self.TVpack.add_packages(self.distrib)
    self.set_statusbar(msg= "Loaded "+str(npack)+" packages.")
#     for row in self.TVpack.packList:
#       row[self.TVpack.COL_VISIBLE]= True
    
  def show_only(self, lista=None):
    if lista==None or lista =={}:
      self.TVpack.TreeView.set_model(self.TVpack.packList)   
      self.TVpack.TreeView.set_search_column(self.TVpack.Options['search_column'])
      for row in self.TVpack.packList:
        name=row[self.TVpack.COL_NAME]
        row[self.TVpack.COL_VISIBLE]= True

    else:
      self.TVpack.TreeView.set_model(self.TVpack.filter)
      self.TVpack.TreeView.set_search_column(self.TVpack.Options['search_column'])
      keys= lista.keys()
      for row in self.TVpack.packList:
        name=row[self.TVpack.COL_NAME]
        row[self.TVpack.COL_VISIBLE]=  name in keys


  def do_install(self, lista):
    self.show_only(lista)
    response= helper.show_question_dlg(_("These are the packages to install.\nProceed?"))
    respuesta= response == gtk.RESPONSE_YES

    # Install the package TODO: It would be much better if the install provide with
    # information about the outcome of the operation
    if respuesta:
      for name,status in lista.iteritems():
        pack= self.distrib.retrieve_package(name)
        self.set_statusbar(msg='Installing package '+name+'. Please wait.')
        if status == INSTALL:
          self.distrib.install_package(pack)
        elif status == UNINSTALL:
          self.distrib.uninstall_package(pack)
        else:
          self.distrib.update_package(pack)

#     for row in self.TVpack.packList:
#       row[self.TVpack.COL_VISIBLE]= True
    self.show_only(None)
    return respuesta


  # ======================================================================
  # ======================================================================
  # Menu and Toolbar =====================================================
      
  def set_statusbar(self, widget=None, msg="", Id=None):
    if not Id:
      Id= self.stbar1.get_context_id("Package installed/removed")
    idmsg= self.stbar1.push(Id, msg)
    return idmsg


  def activate_about(self, action):
    libglade.GladeWrapper.__init__(self, self.gladeFile, "aboutdialog1")
    self.aboutdialog1.connect ("response", lambda d, r: d.destroy())
    self.aboutdialog1.show()


  # exit program =========================================================
  def on_delete_event(self, widget, event):
    self.on_quit_clicked(widget)



  def on_quit_clicked(self, widget, data=None):
    if self.config_gui['save_on_exit']:
      self.config.save_MiKTeX_config(self.config.inifiles[-1])
    else:
      if self.prefmodified:
        response=helper.show_question_dlg(_('Save configuration before exiting?'))
        if response == gtk.RESPONSE_YES:
          self.config.save_MiKTeX_config(self.config.inifiles[-1])      
    gtk.main_quit()
    
  def on_add_clicked(self, widget):
    self.TVpack.on_popadd_activate(widget)

  def on_apply_clicked(self, widget):
    response= self.do_install(self.TVpack.pending_oper)
    if response:
      self.reload_distrib()
      p=[]
      for name, status in self.TVpack.pending_oper.iteritems():
        pack= self.distrib.retrieve_package(name)

        if ((status != pack.installed_state()) and (status != UPDATE)):
          pass ## QUE HACEMOS  ACA?
        else:
          p.append(name)

      for name in p:
        del self.TVpack.pending_oper[name]

    if self.TVpack.pending_oper != {}:
     self.toggle_some(self.TVpack.pending_oper)
     msg=_("The following packages failed:\n")
     for n in self.TVpack.pending_oper.keys():
       msg += n +'\n'
     helper.show_error_dlg(msg)
    else:
      msg=_("You must update your distribution\n in order to let TeX find the recently installed files\nFor TeTeX, run texconfig rehash")
      response=helper.show_info_dlg(msg)
#       response=helper.show_question_dlg(_("You must update your distribution\n in order to let TeX find the recently installed files\nProceed? "))
#       if response == gtk.RESPONSE_YES:
#         self.distrib.update_tex_tree()

      # If everything went OK, pending_oper=={} and we have a full view
    self.show_only(self.TVpack.pending_oper)

  def toggle_some(self, lista):
    for row in self.TVpack.packList:
      name= row[self.TVpack.COL_NAME]
      if name in lista.keys():
        pack= row[self.TVpack.COL_PACK]
        row[self.TVpack.COL_COLOR]= self.TVpack.colores[lista[name]]
        row[self.TVpack.COL_STATE]= lista[name] != UNINSTALL



  def on_show_all_activate(self, widget):
    self.show_only(None)

  def on_info_clicked(self, widget):
    self.TVpack.on_popinfo_activate(widget)

  def on_helppack_clicked(self, widget):
    self.TVpack.on_poppackhelp_activate(widget)

  def on_updatedb_activate(self, widget):
    msg, status=self.distrib.update_db()
    if status:
      self.reload_distrib()
    else:
      helper.show_error_dlg(msg)

  def on_find_updates(self, widget):
    lista= self.distrib.find_all_updates()
    if lista=={}:
      Id= self.stbar1.get_context_id("General")
      myid= self.stbar1.push(Id, _("Not package updatable"))
    else:
      Id= self.stbar1.get_context_id("General")
      myid= self.stbar1.push(Id, _("Showing Packages with available updates"))
      self.show_only(lista)

  def toggle_all_visible(self, widgets):
    """ Toggle the state of all packages currently visible in the Tree """
    for row in self.TVpack.packList:
      if row[self.TVpack.COL_VISIBLE]:
#         oldstate= row[self.TVpack.COL_STATE]
        pack= row[self.TVpack.COL_PACK]
        state= self.TVpack.add_to_install_queue(pack)
        if state == None:
          row[self.TVpack.COL_STATE]= pack.is_installed()
          row[self.TVpack.COL_COLOR]= None
        else:
          row[self.TVpack.COL_STATE]= state != UNINSTALL
          row[self.TVpack.COL_COLOR]= self.TVpack.colores[state]

  
  def mark_all_visible(self, widgets):
    """ Toggle the state of all packages currently visible in the Tree """
    for row in self.TVpack.packList:
      if row[self.TVpack.COL_VISIBLE]:
        pack= row[self.TVpack.COL_PACK]
        name= pack.get_property('name')
        inst= pack.is_installed()
        upd= pack.is_updatable()
        if inst:
          if upd:
            self.TVpack.pending_oper[name]= UPDATE
            row[self.TVpack.COL_COLOR]= self.colores[UPDATE]
        else:
            self.TVpack.pending_oper[name]= INSTALL
            row[self.TVpack.COL_COLOR]= self.TVpack.colores[INSTALL]

        row[self.TVpack.COL_STATE]= True

  def on_refresh_activate(self, widget):
    Id= self.stbar1.get_context_id("Refreshing")
    myid= self.stbar1.push(Id, _("Refreshing the Package's list. Please Wait..."))
    self.TVpack.pending_oper={}
    self.reload_distrib()


  def on_preferences_activate(self, widget):
    Pref= PrefDialog(self.gladeFile, self.config)

    if Pref.modified.keys():
      self.prefmodified=True
      if Pref.modified.has_key('root'):
        self.distrib.set_root_install(Pref.modified['root'])
        if self.distrib.valid:
          self.distrib.refresh_list_packages()
          self.TVpack.packList.clear()
          self.TVpack.add_packages(self.distrib)
        else:
          helper.show_error_dlg('Bad MiKTeX Root Path supplied. Not modified')

        del Pref.modified['root']

      if Pref.modified.has_key('font_info'):
        self.config_gui['font_info']= Pref.modified['font_info']
        if (self.TVpack.fontinfo != pango.FontDescription(self.config_gui['font_info'])):
          self.TVpack.updateinfo(pango.FontDescription(self.config_gui['font_info']))
          del Pref.modified['font_info']
      if Pref.modified.has_key('font_list'):
        self.config_gui['font_list']= Pref.modified['font_list']
        if (self.TVpack.fontlist != pango.FontDescription(self.config_gui['font_list'])):
          self.TVpack.updatelist(pango.FontDescription(self.config_gui['font_list']))
          del Pref.modified['font_list']

      if Pref.modified.has_key('install_color'):
        self.config_gui['install_color']= Pref.modified['install_color']
        del Pref.modified['install_color']
      if Pref.modified.has_key('remove_color'):
        self.config_gui['remove_color']= Pref.modified['remove_color']
        del Pref.modified['remove_color']
      self.TVpack.set_colors(self.config_gui['install_color'],self.config_gui['remove_color'])

      if Pref.modified.has_key('save_on_exit'):
        self.config_gui['save_on_exit']= Pref.modified['save_on_exit']
        del Pref.modified['save_on_exit']

      if Pref.modified.has_key('repository'):
        self.distrib.set_repository(Pref.modified['repository'])
        del Pref.modified['repository']

      for k,v in Pref.modified.iteritems():
        self.config.set_attribute(k, v)

      self.distrib.set_proxy()
      Pref.modified={}



  def on_search_activate(self, widget):
    self.findcbbentry.grab_focus()
    self.findcbbentry.select_region(0,-1)

  def on_findbutton_clicked(self, widget):
    search_string= self.findcbbentry.get_text()
    if search_string.strip() == "":
      # And show the results
      self.show_only(None)
      nitems=0
    else:
      for row in self.TVpack.packList:
        row[self.TVpack.COL_VISIBLE]=True
        
      # Add the list to the history of searched words
      if search_string not in self.searchwords:
        self.searchwords.insert(0,search_string)
      #  Create the dropdown list
      set_model_from_list(self.findcbentry, self.searchwords)
      # Set the scope of the search
      fullsearch= self.findoptcb.get_active()
      # Finally, search
      result=self.distrib.search(search_string, search_desc=fullsearch)
      nitems= len(result.dist.keys())
      # And show the results
      self.show_only(result.dist)

    Id= self.stbar1.get_context_id("General")
    myid= self.stbar1.push(Id, _("Found "+str(nitems)+ " packages."))



  def on_findclear_clicked(self, widget):
    self.findcbbentry.set_text("")
    ##############################################################################
    ##############################    EXPERIMENTAL   #############################
    # Attatch the model "packList" to the treeView "TreeView" from glade file
    self.TVpack.TreeView.set_model(self.TVpack.packList)   
#     self.restricted= False
    # Search Column must be set here AGAIN. Otherwise gets overwritten
    self.TVpack.TreeView.set_search_column(self.TVpack.Options['search_column'])

    for row in self.TVpack.packList:
      row[self.TVpack.COL_VISIBLE]=True

#####################################################################
#####################################################################   
#####################################################################
#####################################################################   
  def main(self):
    # All PyGTK applications must have a gtk.main(). Control ends here
    # and waits for an event to occur (like a key press or mouse event).
    gtk.main()


#####################################################################
#####################################################################   
#####################################################################
#####################################################################   


# If the program is run directly or passed as an argument to the python
# interpreter then create a gMPMwnd instance and show it
def run(filename):
  MainWnd = gMPMwnd(filename, "gMPMwnd")
  gtk.main()


# if __name__ == "__main__":
# #   GTKLOGO_IMAGE = os.path.join(os.path.dirname(__file__),
# #                              'images', 'gtk-logo-rgb.gif')
#   fpath= os.path.dirname(os.path.abspath(__file__))
#   MainWnd = gMPMwnd(filename, "gMPMwnd")
#   gtk.main()
