#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""X Tile module"""

#      x-tile
#      
#      Copyright 2009-2011
#      Giuseppe Penone <giuspen@gmail.com>,
#      Chris Camacho (chris_c) <chris_camacho@yahoo.com>.
#      
#      plus many thanks to  http://tronche.com/gui/x/xlib/
#                      and  http://tripie.sweb.cz/utils/wmctrl/
#
#      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., 51 Franklin Street, Fifth Floor, Boston,
#      MA 02110-1301, USA.

import sys, os, subprocess, gettext, ctypes, ctypes.util, locale
import gtk, gnomeapplet, gobject, gconf
import __builtin__

if os.path.isdir('modules'): MODULES_PATH = 'modules/'
else: MODULES_PATH = '/usr/share/x-tile/modules/'
sys.path.append(MODULES_PATH)
import cons, globs, core

# language installation
gconf_client = gconf.client_get_default()
gconf_client.add_dir(cons.GCONF_DIR, gconf.CLIENT_PRELOAD_NONE)
lang_str = gconf_client.get_string(cons.GCONF_LANG)
if lang_str == None:
   gconf_client.set_string(cons.GCONF_LANG, "default")
   lang_str = "default"
if lang_str != "default": os.environ["LANGUAGE"] = lang_str
try:
   locale.bindtextdomain(cons.APP_NAME, cons.LOCALE_PATH)
   gettext.translation(cons.APP_NAME, cons.LOCALE_PATH).install()
except:
   def _(transl_str):
      return transl_str
   __builtin__._ = _

__builtin__.glob = globs.GlobalsObject()

try:
   libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("libc"))
   libc.prctl(15, cons.APP_NAME, 0, 0, 0)
except: print "libc.prctl not available, the process name will be python and not x-tile"

# icons generation
factory = gtk.IconFactory()
for filename, stock_name in cons.ICONS_FILENAMES:
   pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
   iconset = gtk.IconSet(pixbuf)
   factory.add(stock_name, iconset)
factory.add_default()

APPLET_MENU_XML = '<popup name="button3">'\
         + '<menuitem name="About" verb="About" label="' + _("_About") + '" pixtype="stock" pixname="gtk-about"/>'\
         + '<menuitem name="All_M" verb="All_M" label="' + _("_Maximize All") + '" pixtype="stock" pixname="Maximize Windows"/>'\
         + '<menuitem name="Invert" verb="Invert" label="' + _("_Invert Tiling Order") + '" pixtype="stock" pixname="Invert Tiling"/>'\
         + '<menuitem name="All_4" verb="All_4" label="' + _("Tile All _Quad") + '" pixtype="stock" pixname="Tile Quad"/>'\
         + '<menuitem name="All_TD" verb="All_TD" label="' + _("Tile All Triangle _Down") + '" pixtype="stock" pixname="Tile Triangle Down"/>'\
         + '<menuitem name="All_TU" verb="All_TU" label="' + _("Tile All Triangle _Up") + '" pixtype="stock" pixname="Tile Triangle Up"/>'\
         + '<menuitem name="All_TR" verb="All_TR" label="' + _("Tile All Triangle _Right") + '" pixtype="stock" pixname="Tile Triangle Right"/>'\
         + '<menuitem name="All_TL" verb="All_TL" label="' + _("Tile All Triangle _Left") + '" pixtype="stock" pixname="Tile Triangle Left"/>'\
         + '<menuitem name="All_C2" verb="All_C2" label="' + _("Tile All Custom _2") + '" pixtype="stock" pixname="Custom Exe 2"/>'\
         + '<menuitem name="All_C1" verb="All_C1" label="' + _("Tile All Custom _1") + '" pixtype="stock" pixname="Custom Exe 1"/>'\
         + '<menuitem name="All_H" verb="All_H" label="' + _("Tile All _Horizontally") + '" pixtype="stock" pixname="Tile Horizontally"/>'\
         + '<menuitem name="All_V" verb="All_V" label="' + _("Tile All _Vertically") + '" pixtype="stock" pixname="Tile Vertically"/>'\
         + '<menuitem name="Undo" verb="Undo" label="' + _("U_ndo Tiling") + '" pixtype="stock" pixname="gtk-undo"/>'\
         +'</popup>'

class XTileApplet(gnomeapplet.Applet):
   """The application's Appletizator class"""
   
   def __init__(self, applet, iid):
      """Initializes the Applet, connects the events to the callback functions"""
      self.__gobject_init__()
      self.applet = applet
      size = self.applet.get_size() - 2
      pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(cons.ICON_PLACE, size, size)
      self.image = gtk.Image()
      self.image.set_from_pixbuf(pixbuf)
      self.applet.add(self.image)
      self.applet.connect("button-press-event", self.on_button_press)
      self.applet.connect("change-size", self.reload_image)
      self.applet.connect("destroy-event", self.cleanup)
      self.applet.connect("delete-event", self.cleanup)
      self.applet.set_tooltip_text(_("X Tile\nTile The Windows Upon Your Desktop"))
      self.applet.show_all()
      glob.alive = False
      
   def cleanup(self, *args):
      """Deletes the Applet"""
      del self.applet
      
   def reload_image(self, *args):
      """Reloads the bar icon"""
      size = self.applet.get_size() - 2
      pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(cons.ICON_PLACE, size, size)
      self.image.set_from_pixbuf(pixbuf)
   
   def on_button_press(self, widget, event):
      """When the user clicks upon the Applet..."""
      if (event.type == gtk.gdk.BUTTON_PRESS):
         if (event.button == 1):
            if glob.alive:
               glob.alive = False
               self.gui.quit_application()
            else:
               glob.alive = True
               self.gui = core.XTile(core.InfoModel())
               self.gui.launch_application()
               self.gui.reload_windows_list()
         elif (event.button == 3): self.show_applet_menu()

   def show_applet_menu(self):
      """Opens the applet menu (on gnome bar)"""
      self.applet.setup_menu(APPLET_MENU_XML, cons.get_applet_menu_verbs(self), None)
      
   def hide_and_process(self, command_str):
      """Hide the X Tile Window if Visible, the Process the Command"""
      if glob.alive:
         glob.alive = False
         self.gui.quit_application()
      subprocess.call(command_str, shell=True)
   
   def undo_tiling(self, *args):
      """Just Undo the Latest Tiling Operation"""
      self.hide_and_process("x-tile z &")
   
   def invert_tiling(self, *args):
      """Invert the Order of the Latest Tiling Operation"""
      self.hide_and_process("x-tile i &")
   
   def tile_all_vertically(self, *args):
      """Just tile Vertically all opened windows"""
      self.hide_and_process("x-tile v &")

   def tile_all_horizontally(self, *args):
      """Just tile Horizontally all opened windows"""
      self.hide_and_process("x-tile h &")
      
   def tile_all_triangle_up(self, *args):
      """Just tile Triangle Up all opened windows"""
      self.hide_and_process("x-tile u &")
      
   def tile_all_triangle_down(self, *args):
      """Just tile Triangle Down all opened windows"""
      self.hide_and_process("x-tile d &")
      
   def tile_all_triangle_left(self, *args):
      """Just tile Triangle Left all opened windows"""
      self.hide_and_process("x-tile l &")
      
   def tile_all_triangle_right(self, *args):
      """Just tile Triangle Right all opened windows"""
      self.hide_and_process("x-tile r &")
      
   def tile_all_quad(self, *args):
      """Just tile Quad all opened windows"""
      self.hide_and_process("x-tile q &")
      
   def tile_all_custom_1(self, *args):
      """Just tile Custom 1 all opened windows"""
      self.hide_and_process("x-tile 1 &")
   
   def tile_all_custom_2(self, *args):
      """Just tile Custom 2 all opened windows"""
      self.hide_and_process("x-tile 2 &")
   
   def maximize_all(self, *args):
      """Maximize all opened windows"""
      self.hide_and_process("x-tile m &")
      
   def dialog_about(self, *args):
      """Show the About Dialog and hide it when a button is pressed"""
      glade = core.GladeWidgetsWrapper(cons.GLADE_PATH + 'x-tile.glade', self)
      glade.aboutdialog.set_version(cons.VERSION)
      glade.aboutdialog.run()
      glade.aboutdialog.destroy()
      glade = None

# appletization part
gobject.type_register(XTileApplet)

def x_tile_applet_factory(applet, iid):
   """Calls The Appletization Class"""
   XTileApplet(applet, iid)
   return gtk.TRUE

if len(sys.argv) == 2:
   arg = sys.argv[1]
   if arg == "w":
      # x-tile runs independently from any panel
      x=core.XTile(core.InfoModel())
      x.launch_application()
      x.reload_windows_list()
      gtk.main()
      sys.exit(0)
   elif arg in ["z", "i", "v", "h", "u", "d", "l", "r", "1", "2", "q", "m"]:
      x=core.XTile(core.InfoModel())
      x.launch_application()
      if arg not in ["z", "i"]:
         x.reload_windows_list()
         x.flag_all_rows()
      if arg == "z": x.undo_tiling()
      elif arg == "i": x.invert_tiling()
      elif arg == "v": x.tile_vertically()
      elif arg == "h": x.tile_horizontally()
      elif arg == "u": x.tile_triangle_up()
      elif arg == "d": x.tile_triangle_down()
      elif arg == "l": x.tile_triangle_left()
      elif arg == "r": x.tile_triangle_right()
      elif arg == "q": x.tile_quad()
      elif arg == "1": x.tile_custom_1_run()
      elif arg == "2": x.tile_custom_2_run()
      elif arg == "m": x.maximize_checked_windows()
      sys.exit(0)
   elif arg == "dbg":
      # the applet is reproduced in a little window
      main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
      main_window.set_title("X Tile Applet")
      main_window.connect("destroy", gtk.main_quit)
      main_window.set_default_size(36, 36)
      app = gnomeapplet.Applet()
      x_tile_applet_factory(app, None)
      app.reparent(main_window)
      main_window.show_all()
      gtk.main()
      sys.exit(0)
   else: # -h
      print cons.HELP_TEXT
      sys.exit(0)


def main():
   """Calls the gnomeapplet bonobo_factory function"""
   gnomeapplet.bonobo_factory("OAFIID:GNOME_X_Tile_Applet_Factory",
                              XTileApplet.__gtype__,
                              "X Tile Gnome Applet", "1.0",
                              x_tile_applet_factory)

if __name__ == "__main__": main()
