# -*- coding: UTF8 -*-
# vim: ts=4 et
import rox
from rox import g, OptionsBox
from rcfile import Opt, OptionGroupRC, update_options

app_name = 'OroboROX'
keybutt_size = g.SizeGroup(g.SIZE_GROUP_HORIZONTAL)

# list of modifiers allowed in OroboROX shortcuts
Modifiers = { \
    'Meta_L':'Meta', 'Meta_R':'Meta', \
    'Shift_L':'Shift', 'Shift_R':'Shift', \
    'Control_L':'Control','Control_R':'Control', \
    'Alt_L':'Alt', 'Alt_R':'Alt', \
    'Super_L':'Super', 'Super_R':'Super', \
    'Hyper_L':'Hyper', 'Hyper_R':'Hyper', \
    'Mode_switch':'Modeswitch', \
    'ISO_Level3_Shift':'Isolevel3shift' \
}


    
# i18n of special keys for the button label
KeyCaptions = { 'none':_('None'), \
    'meta':_('Meta'), 'shift':_('Shift'), \
    'control':_('Ctrl'), 'alt':_('Alt'), \
    'super':_('Win'), 'hyper':_('Win'), \
    'modeswitch':_('Alt Gr'), \
    'isolevel3shift':_('Alt Gr'),  \
    'backspace':_('Backspace'), 'tab':_('Tab'), \
    'linedfeed':_('Linefeed'), 'clear':_('Clear'), \
    'return':_('Return'), 'pause':_('Pause'), \
    'escape':_('Esc'), 'delete':_('Del'), \
    'home':_('Home'), 'left':_('Left'), \
    'up':_('Up'), 'right':_('Right'), \
    'down':_('Down'), 'prior':_('Prior'), \
    'page_up':_('Pg Up'), 'next':_('Next'), \
    'page_down':_('Pg Down'), 'end':_('End'), \
    'begin':_('Begin'), 'select':_('Select'), \
    'print':_('Print'), 'exec':_('Exec'), \
    'insert':_('Ins'), 'undo':_('Undo'), \
    'redo':_('Redo'), 'find':_('Find'), \
    'cancel':_('Cancel'), 'help':_('Help'), \
    'break':_('Break'), 'space':_('Space'), \
    'adiaeresis':'ä', 'odiaeresis': 'ö', \
    'udiaeresis':'ü',  'ssharp':'ß', \
    'asciicircum':'^'
}

keyval_name_blacklist = \
['Menu','Scroll_Lock','Caps_Lock','Num_Lock', \
'Kana_Lock','ISO_Lock', 'ISO_Level3_Lock', \
'ISO_Next_Group_Lock', 'Codeinput', 'Kanji' \
]

ModifierMapping = {'mod1':'','mod2':'','mod3':'','mod4':'','mod5':''}

def getmodifiermapping():
    import os, string
    pipe = os.popen('xmodmap -pm', 'r')
    for line in pipe.readlines():
        list = string.split(line, ' ')
        mod_n = list[0]
        if mod_n in ModifierMapping.keys():
            for m in Modifiers.keys():
                if m in list and ModifierMapping[mod_n] =='':
                    ModifierMapping[mod_n] = Modifiers[m]
    pipe.close()


def i18n_caption(keylist):
    import string
    keys = string.split(keylist, '+')
    i18n_shortcut = ''
    for item in keys:
        minuscles = string.lower(item)
        if i18n_shortcut: i18n_shortcut+='+'
        if minuscles in KeyCaptions.keys():
            i18n_shortcut += KeyCaptions[minuscles]
        else:
            i18n_shortcut += item
    return i18n_shortcut
                              
def build_keybutt(wid, node, label, option):
    global keybutt_size
    b = g.Button()
    clr = rox.ButtonMixed(g.STOCK_CLEAR,_('Clear'))
    l = g.Label(label)
    l.set_alignment(1,0.5)
    l.set_padding(6,0)
    need_mod = node.getAttribute('need_mod')

    wid.keylist=""
    
    def clr_clicked(self):
        b.set_label('none') #This should not be translated!
        option.value = 'none'
        wid.options.notify()
        wid.update_revert()

    def keypress_handler(self,kev):
        if kev.keyval==g.keysyms.Escape and not wid.keylist:
            self.destroy()
            return
        key_name = g.gdk.keyval_name(kev.keyval)
        if key_name not in keyval_name_blacklist:
            if wid.keylist: wid.keylist+='+'
            if key_name in Modifiers.keys():
                wid.keylist += Modifiers[key_name]
            else:
                wid.keylist += key_name

    def keycut_handler(self, kev):
        b.set_label(i18n_caption(wid.keylist))
        if wid.keylist: option.value = wid.keylist
        wid.options.notify()
        wid.update_revert()
        wid.keylist=""        
        self.destroy()
        return 
       
    def get_keycut(self):
        w = rox.Window()
        w.set_position(g.WIN_POS_CENTER)
        w.set_title(_('Set shortcut'))
        l = g.Label(_("Press your desired keyboard shortcut\nfor '%s'\nor Escape to cancel...") % label)

        def grab(self,dummy):
            g.gdk.keyboard_grab(self.window,1)
            g.gdk.pointer_grab(self.window,0,0,self.window)
            
    #	def ungrab(self):
    #		g.gdk.keyboard_ungrab()
    #		g.gdk.pointer_ungrab()

        w.connect('key-release-event',keycut_handler)
        w.connect('key-press-event',keypress_handler)
        w.connect('map-event',grab)
    #	w.connect('destroy',ungrab)
        w.add(l)
        w.set_border_width(30)
        w.show_all()
    
    def get():
        return option.value
    def set():
        if option.value:
            b.set_label(i18n_caption(option.value))
        else:
            b.set_label('')
    wid.handlers[option] = (get, set)

    box = g.HBox(False, 4)
    b.connect('clicked',get_keycut)
    #b.set_size_request(180,-1)
    keybutt_size.add_widget(b)
    wid.tips.set_tip(b,_('Click to grab a new keyboard shortcut'))
    wid.tips.set_tip(clr,_('Click to clear the keyboard shortcut'))
    clr.connect('clicked',clr_clicked)
    box.pack_start(l, True, True)
    box.pack_end(clr, False, False)
    box.pack_end(b, False, False)

    return [box]
    
OptionsBox.widget_registry['keybutt'] = build_keybutt

rox.app_options = OptionGroupRC(app_name,'keyboardrc')

Opt('hide_window_key')
Opt('close_window_key')
Opt('toggle_fullscreen_window_key')
Opt('maximize_window_key')
Opt('shade_window_key')
Opt('cycle_windows_key')
Opt('cycle_app_key')
Opt('raise_window_layer_key')
Opt('lower_window_layer_key')
Opt('move_window_up_key')
Opt('move_window_down_key')
Opt('move_window_left_key')
Opt('move_window_right_key')
Opt('next_workspace_key')
Opt('prev_workspace_key')
Opt('add_workspace_key')
Opt('del_workspace_key')
Opt('stick_window_key')
Opt('workspace_1_key')
Opt('workspace_2_key')
Opt('workspace_3_key')
Opt('workspace_4_key')
Opt('workspace_5_key')
Opt('workspace_6_key')
Opt('workspace_7_key')
Opt('workspace_8_key')
Opt('workspace_9_key')
Opt('move_window_next_workspace_key')
Opt('move_window_prev_workspace_key')
Opt('move_window_workspace_1_key')
Opt('move_window_workspace_2_key')
Opt('move_window_workspace_3_key')
Opt('move_window_workspace_4_key')
Opt('move_window_workspace_5_key')
Opt('move_window_workspace_6_key')
Opt('move_window_workspace_7_key')
Opt('move_window_workspace_8_key')
Opt('move_window_workspace_9_key')
Opt('maximize_vert_key')
Opt('maximize_horiz_key')
Opt('resize_window_up_key')
Opt('resize_window_down_key')
Opt('resize_window_left_key')
Opt('resize_window_right_key')
Opt('move_top_left_key')
Opt('move_top_right_key')
Opt('move_bottom_left_key')
Opt('move_bottom_right_key')
Opt('window_ops_modifiers')
Opt('toggle_fullscreen_window_all_key')
Opt('maximize_window_all_key')
Opt('maximize_vert_all_key')
Opt('maximize_horiz_all_key')
Opt('toggle_borders_key')
Opt('raise_window_key')
Opt('show_desktop_key')

rox.app_options.add_notify(update_options)
rox.app_options.notify()
rox.edit_options()
