~ubuntu-branches/ubuntu/lucid/gajim/lucid-security

« back to all changes in this revision

Viewing changes to src/gtkgui_helpers.py

  • Committer: Maia Kozheva
  • Date: 2009-11-25 08:32:36 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: sikon@maia-desktop-20091125083236-hkxrujhn3amehuve
Merged new upstream release 0.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
from common import gajim
56
56
from common import helpers
57
57
 
58
 
gtk.glade.bindtextdomain(i18n.APP, i18n.DIR) 
 
58
gtk.glade.bindtextdomain(i18n.APP, i18n.DIR)
59
59
gtk.glade.textdomain(i18n.APP)
60
60
 
61
61
screen_w = gtk.gdk.screen_width()
71
71
        completion list consists of (Pixbuf, Text) rows'''
72
72
        completion = gtk.EntryCompletion()
73
73
        liststore = gtk.ListStore(gtk.gdk.Pixbuf, str)
74
 
        
 
74
 
75
75
        render_pixbuf = gtk.CellRendererPixbuf()
76
76
        completion.pack_start(render_pixbuf, expand = False)
77
77
        completion.add_attribute(render_pixbuf, 'pixbuf', 0)
78
 
        
 
78
 
79
79
        render_text = gtk.CellRendererText()
80
80
        completion.pack_start(render_text, expand = True)
81
81
        completion.add_attribute(render_text, 'text', 1)
83
83
        completion.set_model(liststore)
84
84
        entry.set_completion(completion)
85
85
        return liststore
86
 
        
87
 
        
 
86
 
 
87
 
88
88
def popup_emoticons_under_button(menu, button, parent_win):
89
89
        ''' pops emoticons menu under button, which is in parent_win'''
90
90
        window_x1, window_y1 = parent_win.get_origin()
91
91
        def position_menu_under_button(menu):
92
92
                # inline function, which will not keep refs, when used as CB
93
93
                button_x, button_y = button.allocation.x, button.allocation.y
94
 
                
 
94
 
95
95
                # now convert them to X11-relative
96
96
                window_x, window_y = window_x1, window_y1
97
97
                x = window_x + button_x
98
98
                y = window_y + button_y
99
99
 
100
 
                menu_width, menu_height = menu.size_request()
 
100
                menu_height = menu.size_request()[1]
101
101
 
102
102
                ## should we pop down or up?
103
103
                if (y + button.allocation.height + menu_height
113
113
                return (x, y, push_in)
114
114
 
115
115
        menu.popup(None, None, position_menu_under_button, 1, 0)
116
 
        
 
116
 
117
117
def get_theme_font_for_option(theme, option):
118
118
        '''return string description of the font, stored in
119
119
        theme preferences'''
128
128
        fd = pango.FontDescription(font_name)
129
129
        fd.merge(font_desc, True)
130
130
        return fd.to_string()
131
 
        
 
131
 
132
132
def get_default_font():
133
133
        '''Get the desktop setting for application font
134
134
        first check for GNOME, then Xfce and last KDE
135
135
        it returns None on failure or else a string 'Font Size' '''
136
 
        
 
136
 
137
137
        try:
138
138
                import gconf
139
139
                # in try because daemon may not be there
150
150
        # and http://freedesktop.org/Standards/basedir-spec
151
151
        xdg_config_home = os.environ.get('XDG_CONFIG_HOME', '')
152
152
        if xdg_config_home == '':
153
 
                xdg_config_home = os.path.expanduser('~/.config') # default     
 
153
                xdg_config_home = os.path.expanduser('~/.config') # default
154
154
        xfce_config_file = os.path.join(xdg_config_home, 'xfce4/mcs_settings/gtk.xml')
155
 
        
 
155
 
156
156
        kde_config_file = os.path.expanduser('~/.kde/share/config/kdeglobals')
157
 
        
 
157
 
158
158
        if os.path.exists(xfce_config_file):
159
159
                try:
160
160
                        for line in open(xfce_config_file):
164
164
                except Exception:
165
165
                        #we talk about file
166
166
                        print >> sys.stderr, _('Error: cannot open %s for reading') % xfce_config_file
167
 
        
 
167
 
168
168
        elif os.path.exists(kde_config_file):
169
169
                try:
170
170
                        for line in open(kde_config_file):
179
179
                except Exception:
180
180
                        #we talk about file
181
181
                        print >> sys.stderr, _('Error: cannot open %s for reading') % kde_config_file
182
 
        
 
182
 
183
183
        return None
184
 
        
 
184
 
185
185
def autodetect_browser_mailer():
186
186
        # recognize the environment and set appropriate browser/mailer
187
187
        if user_runs_gnome():
190
190
                gajim.config.set('openwith', 'kfmclient exec')
191
191
        elif user_runs_xfce():
192
192
                gajim.config.set('openwith', 'exo-open')
193
 
        elif user_runs_osx():
194
 
                gajim.config.set('openwith', 'open')
195
193
        else:
196
194
                gajim.config.set('openwith', 'custom')
197
195
 
207
205
                return True
208
206
        return False
209
207
 
210
 
def user_runs_osx():
211
 
        return sys.platform == 'darwin'
212
 
 
213
208
def get_running_processes():
214
209
        '''returns running processes or None (if not /proc exists)'''
215
210
        if os.path.isdir('/proc'):
229
224
                files = filter(str.isdigit, files)
230
225
 
231
226
                # files that aren't directories...
232
 
                files = filter(lambda f:os.path.isdir('/proc/' + f), files)
 
227
                files = [f for f in files if os.path.isdir('/proc/' + f)]
233
228
 
234
229
                # processes owned by somebody not running gajim...
235
230
                # (we check if we have access to that file)
236
 
                files = filter(lambda f:os.access('/proc/' + f +'/exe', os.F_OK), files)
 
231
                files = [f for f in files if os.access('/proc/' + f +'/exe', os.F_OK)]
237
232
 
238
233
                # be sure that /proc/[number]/exe is really a symlink
239
234
                # to avoid TBs in incorrectly configured systems
240
 
                files = filter(lambda f:os.path.islink('/proc/' + f + '/exe'), files)
 
235
                files = [f for f in files if os.path.islink('/proc/' + f + '/exe')]
241
236
 
242
237
                # list of processes
243
238
                processes = [os.path.basename(os.readlink('/proc/' + f +'/exe')) for f in files]
244
 
                
 
239
 
245
240
                return processes
246
241
        return []
247
242
 
371
366
        '''checks if we are svn or normal user and returns abspath to asked script
372
367
        if want_type is True we return 'svn' or 'install' '''
373
368
        if os.path.isdir('.svn'): # we are svn user
374
 
                type = 'svn'
 
369
                type_ = 'svn'
375
370
                cwd = os.getcwd() # it's always ending with src
376
371
 
377
372
                if scriptname == 'gajim-remote':
378
373
                        path_to_script = cwd + '/gajim-remote.py'
379
 
                
 
374
 
380
375
                elif scriptname == 'gajim':
381
376
                        script = '#!/bin/sh\n' # the script we may create
382
377
                        script += 'cd %s' % cwd
383
378
                        path_to_script = cwd + '/../scripts/gajim_sm_script'
384
 
                                
 
379
 
385
380
                        try:
386
381
                                if os.path.exists(path_to_script):
387
382
                                        os.remove(path_to_script)
397
392
                                print >> sys.stderr, s
398
393
 
399
394
        else: # normal user (not svn user)
400
 
                type = 'install'
 
395
                type_ = 'install'
401
396
                # always make it like '/usr/local/bin/gajim'
402
397
                path_to_script = helpers.is_in_path(scriptname, True)
403
 
                
404
 
        
 
398
 
 
399
 
405
400
        if want_type:
406
 
                return path_to_script, type
 
401
                return path_to_script, type_
407
402
        else:
408
403
                return path_to_script
409
404
 
458
453
        root_window = gtk.gdk.screen_get_default().get_root_window()
459
454
        # current user's vd
460
455
        current_virtual_desktop_no = get_current_desktop(root_window)
461
 
        
 
456
 
462
457
        # vd roster window is in
463
458
        window_virtual_desktop = get_current_desktop(window.window)
464
459
 
476
471
        '''returns True if file is locked (WINDOWS ONLY)'''
477
472
        if os.name != 'nt': # just in case
478
473
                return
479
 
        
 
474
 
480
475
        if not HAS_PYWIN32:
481
476
                return
482
 
        
 
477
 
483
478
        secur_att = pywintypes.SECURITY_ATTRIBUTES()
484
479
        secur_att.Initialize()
485
 
        
 
480
 
486
481
        try:
487
482
                # try make a handle for READING the file
488
483
                hfile = win32file.CreateFile(
494
489
                        win32con.FILE_ATTRIBUTE_NORMAL, # normal file
495
490
                        0                                                               # no attr. template
496
491
                )
497
 
        except pywintypes.error, e:
 
492
        except pywintypes.error:
498
493
                return True
499
494
        else: # in case all went ok, close file handle (go to hell WinAPI)
500
495
                hfile.Close()
523
518
def get_scaled_pixbuf(pixbuf, kind):
524
519
        '''returns scaled pixbuf, keeping ratio etc or None
525
520
        kind is either "chat", "roster", "notification", "tooltip", "vcard"'''
526
 
        
 
521
 
527
522
        # resize to a width / height for the avatar not to have distortion
528
523
        # (keep aspect ratio)
529
524
        width = gajim.config.get(kind + '_avatar_width')
629
624
                for extension in ('.png', '.jpeg'):
630
625
                        path_to_local_file_full = path_to_local_file + extension
631
626
                        if os.path.exists(path_to_local_file_full):
632
 
                                return path_to_local_file_full 
 
627
                                return path_to_local_file_full
633
628
                for extension in ('.png', '.jpeg'):
634
629
                        path_to_file_full = path_to_file + extension
635
630
                        if os.path.exists(path_to_file_full):
641
636
        ask sys.getfilesystemencoding() in POSIX
642
637
        file_paths MUST be LIST'''
643
638
        file_paths_list = list()
644
 
        
 
639
 
645
640
        if os.name == 'nt': # decode as UTF-8 under Windows
646
641
                for file_path in file_paths:
647
642
                        file_path = file_path.decode('utf8')
656
651
                                except Exception:
657
652
                                        pass
658
653
                        file_paths_list.append(file_path)
659
 
        
 
654
 
660
655
        return file_paths_list
661
656
 
662
657
def possibly_set_gajim_as_xmpp_handler():
663
658
        '''registers (by default only the first time) xmmp: to Gajim.'''
664
659
        path_to_dot_kde = os.path.expanduser('~/.kde')
665
660
        if os.path.exists(path_to_dot_kde):
666
 
                path_to_kde_file = os.path.join(path_to_dot_kde, 
 
661
                path_to_kde_file = os.path.join(path_to_dot_kde,
667
662
                        'share/services/xmpp.protocol')
668
663
        else:
669
664
                path_to_kde_file = None
795
790
                # Save image
796
791
                try:
797
792
                        pixbuf.save(file_path, type_)
798
 
                except:
 
793
                except Exception:
799
794
                        if os.path.exists(file_path):
800
795
                                os.remove(file_path)
801
796
                        new_file_path = '.'.join(file_path.split('.')[:-1]) + '.jpeg'
808
803
                        dialog.destroy()
809
804
 
810
805
        def on_ok(widget):
811
 
                def on_ok2(file_path, pixbuf):
812
 
                        pixbuf.save(file_path, 'jpeg')
813
 
                        dialog.destroy()
814
 
 
815
806
                file_path = dialog.get_filename()
816
807
                file_path = decode_filechooser_file_paths((file_path,))[0]
817
808
                if os.path.exists(file_path):
818
809
                        # check if we have write permissions
819
810
                        if not os.access(file_path, os.W_OK):
820
811
                                file_name = os.path.basename(file_path)
821
 
                                dialogs.ErrorDialog(_('Cannot overwrite existing file "%s"' % 
 
812
                                dialogs.ErrorDialog(_('Cannot overwrite existing file "%s"' %
822
813
                                        file_name),
823
814
                                _('A file with this name already exists and you do not have '
824
815
                                'permission to overwrite it.'))
841
832
        def on_cancel(widget):
842
833
                dialog.destroy()
843
834
 
844
 
        dialog = dialogs.FileChooserDialog(title_text=_('Save Image as...'), 
 
835
        dialog = dialogs.FileChooserDialog(title_text=_('Save Image as...'),
845
836
                action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,
846
837
                gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK),
847
838
                default_response=gtk.RESPONSE_OK,
872
863
        combobox.show_all()
873
864
        return combobox
874
865
 
875
 
def load_iconset(path, pixbuf2 = None, transport = False):
 
866
def create_list_multi(value_list, selected_values=None):
 
867
        '''Value_list is [(label1, value1), ]'''
 
868
        liststore = gtk.ListStore(str, str)
 
869
        treeview = gtk.TreeView(liststore)
 
870
        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
 
871
        treeview.set_headers_visible(False)
 
872
        col = gtk.TreeViewColumn()
 
873
        treeview.append_column(col)
 
874
        cell = gtk.CellRendererText()
 
875
        col.pack_start(cell, True)
 
876
        col.set_attributes(cell, text=0)
 
877
        for value in value_list:
 
878
                iter = liststore.append(value)
 
879
                if value[1] in selected_values:
 
880
                        treeview.get_selection().select_iter(iter)
 
881
        treeview.show_all()
 
882
        return treeview
 
883
 
 
884
def load_iconset(path, pixbuf2=None, transport=False):
876
885
        '''load full iconset from the given path, and add
877
886
        pixbuf2 on top left of each static images'''
878
887
        path += '/'
879
888
        if transport:
880
 
                list = ('online', 'chat', 'away', 'xa', 'dnd', 'offline',
 
889
                list_ = ('online', 'chat', 'away', 'xa', 'dnd', 'offline',
881
890
                        'not in roster')
882
891
        else:
883
 
                list = ('connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 
892
                list_ = ('connecting', 'online', 'chat', 'away', 'xa', 'dnd',
884
893
                        'invisible', 'offline', 'error', 'requested', 'event', 'opened',
885
894
                        'closed', 'not in roster', 'muc_active', 'muc_inactive')
886
895
                if pixbuf2:
887
 
                        list = ('connecting', 'online', 'chat', 'away', 'xa', 'dnd',
 
896
                        list_ = ('connecting', 'online', 'chat', 'away', 'xa', 'dnd',
888
897
                                'offline', 'error', 'requested', 'event', 'not in roster')
889
 
        return _load_icon_list(list, path, pixbuf2)
 
898
        return _load_icon_list(list_, path, pixbuf2)
890
899
 
891
900
def load_icon(icon_name):
892
901
        '''load an icon from the iconset in 16x16'''
948
957
                image = gtk.Image()
949
958
                image.show()
950
959
                imgs[icon] = image
951
 
                for file in files: # loop seeking for either gif or png
952
 
                        if os.path.exists(file):
953
 
                                image.set_from_file(file)
 
960
                for file_ in files: # loop seeking for either gif or png
 
961
                        if os.path.exists(file_):
 
962
                                image.set_from_file(file_)
954
963
                                if pixbuf2 and image.get_storage_type() == gtk.IMAGE_PIXBUF:
955
964
                                        # add pixbuf2 on top-left corner of image
956
965
                                        pixbuf1 = image.get_pixbuf()
966
975
        '''initialise jabber_state_images dict'''
967
976
        iconset = gajim.config.get('iconset')
968
977
        if iconset:
969
 
                path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
970
 
                if not os.path.exists(path):
 
978
                if helpers.get_iconset_path(iconset):
 
979
                        path = os.path.join(helpers.get_iconset_path(iconset), '16x16')
 
980
                        if not os.path.exists(path):
 
981
                                iconset = gajim.config.DEFAULT_ICONSET
 
982
                                gajim.config.set('iconset', iconset)
 
983
                else:
971
984
                        iconset = gajim.config.DEFAULT_ICONSET
 
985
                        gajim.config.set('iconset', iconset)
972
986
        else:
973
987
                iconset = gajim.config.DEFAULT_ICONSET
 
988
                gajim.config.set('iconset', iconset)
974
989
 
975
990
        path = os.path.join(helpers.get_iconset_path(iconset), '32x32')
976
991
        gajim.interface.jabber_state_images['32'] = load_iconset(path)
986
1001
        make_jabber_state_images()
987
1002
        gajim.interface.roster.update_jabber_state_images()
988
1003
 
 
1004
def label_set_autowrap(widget):
 
1005
        '''Make labels automatically re-wrap if their containers are resized.
 
1006
        Accepts label or container widgets.'''
 
1007
        if isinstance (widget, gtk.Container):
 
1008
                children = widget.get_children()
 
1009
                for i in xrange (len (children)):
 
1010
                        label_set_autowrap(children[i])
 
1011
        elif isinstance(widget, gtk.Label):
 
1012
                widget.set_line_wrap(True)
 
1013
                widget.connect_after('size-allocate', __label_size_allocate)
 
1014
 
 
1015
def __label_size_allocate(widget, allocation):
 
1016
        '''Callback which re-allocates the size of a label.'''
 
1017
        layout = widget.get_layout()
 
1018
 
 
1019
        lw_old, lh_old = layout.get_size()
 
1020
        # fixed width labels
 
1021
        if lw_old/pango.SCALE == allocation.width:
 
1022
                return
 
1023
 
 
1024
        # set wrap width to the pango.Layout of the labels ###
 
1025
        layout.set_width (allocation.width * pango.SCALE)
 
1026
        lw, lh = layout.get_size ()
 
1027
 
 
1028
        if lh_old != lh:
 
1029
                widget.set_size_request (-1, lh / pango.SCALE)
 
1030
 
989
1031
# vim: se ts=3: