gtkutil.py :  » Game-2D-3D » PyScrabble » pyscrabble-1.6.2 » pyscrabble » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » PyScrabble 
PyScrabble » pyscrabble 1.6.2 » pyscrabble » gtkutil.py
from pyscrabble import constants
from pyscrabble import gtkconstants
from pyscrabble import manager
from pyscrabble import util
from pyscrabble import gui
from twisted.internet import reactor
import gtk
import pango

def fatalError(data):
    '''
    A Fatal error has occurred.  Usually it means the connection to the server has been lost.
    
    Show a dialog and then quit
    
    @param data: ErrorMessage data
    '''
    
    s = _("Error: A Fatal Error has occurred")
    s1 = _("The application will now close")
    dialog = gtk.MessageDialog(parent=None, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format="")
    dialog.set_title(_("Error: Fatal Error"))
    dialog.set_markup("<big>%s: %s. %s.</big>" % (s,data.getErrorMessage(),s1))
    response = dialog.run()
    reactor.stop()

def setupStockItems():
    '''
    Setup stock images
    '''
    widget = gtk.DrawingArea()
    
    factory = gtk.IconFactory()
    
    r = manager.ResourceManager()
    
    buf = gtk.gdk.pixbuf_new_from_file( r["resources"]["images"][gtkconstants.STOCK_SEND_IM_FILE] )
    icon = gtk.IconSet(buf)
    factory.add( gtkconstants.STOCK_SEND_IM, icon )
    
    factory.add( gtkconstants.STOCK_COPY_URL, gtk.IconSet(widget.render_icon(gtk.STOCK_COPY, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_COPY_EMAIL, gtk.IconSet(widget.render_icon(gtk.STOCK_COPY, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_OPEN_URL, gtk.IconSet(widget.render_icon(gtk.STOCK_JUMP_TO, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_OFFLINE_MESSAGE, gtk.IconSet(widget.render_icon(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_DEFINE, gtk.IconSet(widget.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_SEND_MOVE, gtk.IconSet(widget.render_icon(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_RESET_DEFAULT, gtk.IconSet(widget.render_icon(gtk.STOCK_UNDO, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_PASS, gtk.IconSet(widget.render_icon(gtk.STOCK_NO, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_TRADE_LETTERS, gtk.IconSet(widget.render_icon(gtk.STOCK_UNDO, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_SHUFFLE, gtk.IconSet(widget.render_icon(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_REGISTER, gtk.IconSet(widget.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_MENU)) )
    factory.add( gtkconstants.STOCK_ADD_HOSTNAME, gtk.IconSet(widget.render_icon(gtk.STOCK_COPY, gtk.ICON_SIZE_MENU)) )
    
    factory.add_default()
    
    widget.destroy()
    widget = None

def showAbout(menu):
    '''
    Show about dialog
    
    @param menu:
    '''
    r = manager.ResourceManager()
    dialog = gtk.AboutDialog()
    dialog.set_name( "PyScrabble" )
    dialog.set_authors( ["Kevin Conaway", "Dennis Harrison -- Testing", "Mark Lee -- Patches", "Jaderi -- Testing"] )
    dialog.set_comments( "For Erin" )
    dialog.set_website( constants.ONLINE_SITE )
    dialog.set_website_label( constants.ONLINE_SITE )
    dialog.set_logo( gtk.gdk.pixbuf_new_from_file(r["resources"]["images"]["py.ico"]) )
    dialog.set_translator_credits(_('translator-credits'))
    gtk.about_dialog_set_url_hook(util.showUrl, data=constants.ONLINE_SITE)
    dialog.set_version(constants.VERSION)
    dialog.show()

def getSelectedItem(view, col):
    '''
    Get selected column from aTreeView import 
    
    @param view: TreeView
    @param col: Column number
    '''
    
    sel = view.get_selection()
    model, iter = sel.get_selected()
    
    if (iter == None):
        return None
    
    return model.get_value(iter, col)

def copyToClipboard(widget, data):
    '''
    Copy to clipboard
    
    @param widget: Widget that activated this callback
    @param data: Data to add to clipboard
    '''
    clipboard = gtk.clipboard_get()
    clipboard.set_text(data)

def colorReset_cb(widget, key, val, button, enable):
    '''
    Reset a color option to the default option
    
    @param widget:
    @param key:
    @param val:
    @param button:
    @param enable:
    '''
    o = manager.OptionManager()
    enable.set_active(True)
    o.set_option(key, val)
    button.set_color( gtk.gdk.color_parse(val) )
    button.show()
        
def colorSet_cb(widget, key, enable):
    '''
    Set color preference
    
    @param widget: Color button
    @param key: Preference key
    @param enable: Enable checkbox
    '''
    o = manager.OptionManager()
    enable.set_active(True)
    c = widget.get_color()
    color = util.colorToHexString(c.red,c.green,c.blue)
    o.set_option(key, color)

def toggleOption_cb(widget, option):
    '''
    Notification preference toggled.
    
    Set the option name to the value of widget.get_active()
    
    @param widget: Widget that activated this callback
    @param option: Option name
    '''
    o = manager.OptionManager()
    o.set_option(option, int(widget.get_active()))

def createColorPreference(optionVal, defaultOptionVal, enableOptionVal, label, tips, tipText):
    '''
    Create color preference box
    
    @param optionVal:
    @param defaultOptionVal:
    @param enableOptionVal:
    @param label:
    @param tips:
    @param tipText:
    '''
    o = manager.OptionManager()
    opt = o.get_default_option(optionVal, defaultOptionVal) #option,default
    
    enable = gtk.CheckButton(_('Enable'))
    enable.connect("toggled", toggleOption_cb, enableOptionVal) #enable option
    enable.set_active(o.get_default_bool_option(enableOptionVal, True)) #enable option
    cb = gtk.ColorButton(gtk.gdk.color_parse(opt))
    cb.connect("color-set", colorSet_cb, optionVal, enable) #option
    b = gtk.Button(stock=gtkconstants.STOCK_RESET_DEFAULT)
    b.connect("clicked", colorReset_cb, optionVal, defaultOptionVal, cb, enable)
    bbox = gtk.HButtonBox()
    bbox.add( cb )
    bbox.add( b )
    bbox.add( enable )
    hbox = gtk.HBox(False, 5)
    l = createLeftJustifiedLabel( label ) # label
    hbox.pack_start( l, True, True, 5 )
    hbox.pack_start( bbox, False, False, 5)
    tips.set_tip(cb,tipText) #tips
    return hbox

def createLeftJustifiedLabel(text):
    '''
    Create a left justified label
    
    @param text: Label text
    '''
    l = gtk.Label(text)
    l.set_alignment(0., 0.4)
    return l
    

def getIterByColumn(model, col, value):
    '''
    Get a TreeIter by col num and value
    
    @param model: TreeModel
    @param col: Column Number
    @param value: Column Value
    @return: TreeIter
    '''
    iter = model.get_iter_root()
    
    while iter is not None:
        val = model.get_value(iter, col)
        if val == value:
            return iter
        iter = model.iter_next(iter)
    

def createToolButton(stock_id, label):
    '''
    Create a toolbar button
    
    @param stock_id: Stock_id
    @param label: Label text
    '''
    
    if label is not None:
        button = gtk.ToolButton(gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_MENU), label=label)
    else:
        button = gtk.ToolButton(stock_id=stock_id)
    button.set_is_important(True)
    return button

class LetterPlaceHolder(gtk.Fixed):
    '''
    Class to be used when a letter is dragged out of the rack
    
    This empty placeholder will take the spot of the Letter
    '''
    
    def __init__(self, letterBox, game_frame):
        '''
        Constructor
        
        @param letterBox: Box that holds the GameLetters
        @param game_frame: GameFrame instance
        '''
        
        gtk.Fixed.__init__(self)
        self.set_size_request( constants.TILE_WIDTH, constants.TILE_HEIGHT )
        
        self.letterBox = letterBox
        self.game_frame = game_frame
        
        self.handler_id = self.connect("drag_data_received", self.swapLetter);
        self.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [( "image/x-xpixmap", 0, 81 )], gtk.gdk.ACTION_COPY)
    
    def swapLetter(self, widget, context, x, y, selection, targetType, eventType):
        '''
        
        @param widget: Placeholder
        @param context: Drag context
        @param x:
        @param y:
        @param selection:
        @param targetType:
        @param eventType:
        '''
        letter = context.get_source_widget()
        
        if isinstance(letter, gui.pieces.GameTile):
            self.game_frame.removeMove(letter, letter.x, letter.y)
            if letter.getLetter().isBlank():
                letter.getLetter().setLetter("")
            letter = gui.pieces.GameLetter(letter.getLetter(), self.letterBox)
        
        if not isinstance(letter, gui.pieces.GameLetter):
            return
        
        letters = self.letterBox.get_children()
        self.letterBox.foreach(lambda w: self.letterBox.remove(w))
        
        for l in letters:
            if id(l) == id(widget):
                self.letterBox.pack_start(letter, False, False, 0)
            elif id(l) == id(letter):
                self.letterBox.pack_start(widget, False, False, 0)
            else:
                self.letterBox.pack_start(l, False, False, 0)
        self.letterBox.show_all()
        
    def activate(self):
        '''
        Do nothing
        '''
        return True
    
    def deactivate(self):
        '''
        Do nothing
        '''
        return True
        
        
        
        
class Popup(gtk.Window):
    
    DELAY = 0.02
    WIDTH_BUFFER = 0
    COUNT = 0
    COUNT_BUFFER = 30
    HEIGHT_BUFFER = 0
    MAX_INTERVALS = 20
    TIMEOUT = 3
    
    def __init__(self, title, text):
        '''
        Toaster popup window
        
        @param title:
        @param text:
        '''
        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
        
        self.set_default_size(150,100)
        self.move(gtk.gdk.screen_width(),gtk.gdk.screen_height()) # Start the window off to the side somewhere
        self.connect("map-event", self.onMapEvent_cb)
        self.connect("destroy", self.onDestroy_cb)
        self.connect("delete-event", self.close_cb)
        
        o = manager.OptionManager()
        self.timeout = int( o.get_default_option(constants.OPTION_POPUP_TIMEOUT, Popup.TIMEOUT) )
        self.intervals = 0
        
        l = gtk.Label()
        l.set_markup("""<span background="#FFFFFF" weight="bold">%s</span>""" % text)
        hbox = gtk.HBox(False, 5)
        hbox.pack_start( gtk.image_new_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON), False, False, 5)
        hbox.pack_start( l, False, False, 3)
        
        box = gtk.EventBox()
        box.add( hbox )
        box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF"))
        box.connect("button-press-event", self.close_cb)
        
        l = gtk.Label()
        l.set_markup("""<span weight="bold" foreground="#FFFFFF">%s</span>""" % title)
        header = gtk.EventBox()
        header.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#6699ff"))
        header.add( l )
        header.connect("button-press-event", self.close_cb)
        
        vbox = gtk.VBox(False, 0)
        vbox.pack_start(header, False, False, 0)
        vbox.pack_start(gtk.HSeparator(), False, False, 0)
        vbox.pack_start(box, True, True, 0)
        
        frame = gtk.Frame()
        frame.set_shadow_type( gtk.SHADOW_ETCHED_IN )
        frame.add(vbox)
        
        self.add( frame )
        
        self.show_all()
    
    def close_cb(self, widget=None, event=None):
        '''
        Close callback
        
        @param widget:
        @param event:
        '''
        width, height = self.get_size()
        Popup.HEIGHT_BUFFER -= height
        if Popup.HEIGHT_BUFFER < 0:
            Popup.HEIGHT_BUFFER = 0
        Popup.COUNT = Popup.COUNT - 1
        self.destroy()
    
    def onDestroy_cb(self, widget):
        '''
        Destroy callback
        
        @param widget:
        '''
        pass
    
    def onMapEvent_cb(self, widget, event):
        '''
        Callback when widget is mapped to the display
        
        Show the window and set the move timer
        
        @param widget:
        @param event:
        '''
        self.set_gravity(gtk.gdk.GRAVITY_SOUTH_EAST)
        width, height = self.get_size()
        
        self.count = Popup.COUNT
        Popup.COUNT = Popup.COUNT + 1
        
        self.max_height = Popup.HEIGHT_BUFFER
        Popup.HEIGHT_BUFFER += height
        
        self.move(gtk.gdk.screen_width() - (width + Popup.WIDTH_BUFFER), gtk.gdk.screen_height())
        reactor.callLater(Popup.DELAY, self.moveWindow, up=True)
        return True
    
    def moveWindow(self, up=True):
        '''
        Move the window
        
        @param up: True to move the window up, False down
        '''
        if up:
            self.intervals = self.intervals + 1
        else:
            self.intervals = self.intervals - 1
        
        width, height = self.get_size()
        
        w = gtk.gdk.screen_width() - (width + Popup.WIDTH_BUFFER)
        h = gtk.gdk.screen_height() - (self.max_height * self.intervals / Popup.MAX_INTERVALS) - ((height+self.getCountBuffer()) * self.intervals / Popup.MAX_INTERVALS)
        
        self.move(w, h)
        
        if self.intervals == Popup.MAX_INTERVALS:
            reactor.callLater(self.timeout, self.moveWindow, False)
        elif self.intervals == 0:
            self.close_cb()
        else:
            reactor.callLater(Popup.DELAY, self.moveWindow, up)
    
    def getCountBuffer(self):
        '''
        If there are other windows shown, we need to adjust the height so the windows are stacked
        '''
        return util.ternary(Popup.COUNT == 1, Popup.COUNT_BUFFER, Popup.COUNT_BUFFER - Popup.COUNT)


class TaggableTextView(gtk.TextView):
    '''
    TextView that will markup text based on its content
    
    Currently handles
    - URLs
    - Email addresses
    '''
    
    def __init__(self, buffer=None):
        '''
        Constructor
        
        @param buffer: gtk.TextBuffer
        '''
        gtk.TextView.__init__(self, buffer)
        self.connect("motion-notify-event", self.motionNotify_cb)
    
    def insert_text(self, text):
        '''
        Insert text into buffer
        
        @param text: Text
        '''
        
        self.insert_text_with_tags(text, None)
    
    def insert_text_with_tags(self, text, tags):
        '''
        Insert text with tags
        
        @param text: Text
        @param tags: Tags
        '''
        
        buf = self.get_buffer()
        items = str(text).split()
        
        for item in items:
            t = None
            trailing = None
            if util.isURL(item):
                item, trailing = util.getURL(item)
                t = buf.create_tag(foreground="blue", underline=pango.UNDERLINE_SINGLE)
                t.set_data(gtkconstants.TAG_TYPE, gtkconstants.LINK_TAG)
                t.connect("event", self.tagEvent, item)
            elif util.isEmail(item):
                item, trailing = util.getEmail(item)
                t = buf.create_tag(foreground="blue", underline=pango.UNDERLINE_SINGLE)
                t.connect("event", self.tagEvent, '%s%s' % ('mailto:',item))
                t.set_data(gtkconstants.TAG_TYPE, gtkconstants.EMAIL_TAG)
            
            if t:    
                if tags:
                    buf.insert_with_tags(buf.get_end_iter(), '%s' % item, tags, t)
                else:
                    buf.insert_with_tags(buf.get_end_iter(), '%s' % item, t)
            else:
                if tags:
                    buf.insert_with_tags(buf.get_end_iter(), item, tags)
                else:
                    buf.insert(buf.get_end_iter(), item)
            
            if trailing is not None:
                for item in trailing:
                    buf.insert(buf.get_end_iter(), item)
            buf.insert(buf.get_end_iter(), ' ')
                
        buf.insert(buf.get_end_iter(), '\n')
        
        buf.create_mark("end", buf.get_end_iter())
        self.scroll_to_mark(buf.get_mark("end"), 0.0)
    
    def tagEvent(self, tag, widget, event, iter, data):
        '''
        Tag event
        
        @param tag: TextTag
        @param widget: self
        @param event: Event
        @param iter: TextIter
        @param data: URL
        '''
        
        if event.type == gtk.gdk.BUTTON_PRESS:
            if event.button in (1,2):
                util.showUrl(None, data, None)
                return True
            if event.button == 3:
                message_menu = gtk.Menu()
                
                type = tag.get_data(gtkconstants.TAG_TYPE)
                
                if type == gtkconstants.LINK_TAG:
                    item = gtk.ImageMenuItem(stock_id=gtkconstants.STOCK_COPY_URL)
                    item.connect("activate", copyToClipboard, data)
                    message_menu.add(item)
                    
                    message_menu.add( gtk.SeparatorMenuItem() )
                    
                    item = gtk.ImageMenuItem(stock_id=gtkconstants.STOCK_OPEN_URL)
                    item.connect("activate", util.showUrl, data, None)
                    message_menu.add(item)
                if type == gtkconstants.EMAIL_TAG:
                    item = gtk.ImageMenuItem(stock_id=gtkconstants.STOCK_COPY_EMAIL)
                    item.connect("activate", copyToClipboard, data.lstrip('mailto:'))
                    message_menu.add(item)
                
                
                message_menu.show_all()
                message_menu.popup(None, None, None, event.button, event.time)
                return True
                
    def motionNotify_cb(self, widget, event):
        '''
        Motion notify over the TextView.  If we hover over a link tag, change the pointer
        
        @param widget:
        @param event:
        '''
        
        x,y = widget.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, event.x, event.y)
       
        iter = widget.get_iter_at_location(x,y)
        tags = iter.get_tags()
       
        t = None
        for tag in tags:
            type = tag.get_data(gtkconstants.TAG_TYPE)
            if type in (gtkconstants.LINK_TAG, gtkconstants.EMAIL_TAG):
                t = tag
                break
       
        if t:
            widget.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( gtk.gdk.Cursor(gtk.gdk.HAND2))
        else:
            widget.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor( gtk.gdk.Cursor(gtk.gdk.XTERM))
       
        return False
        
class EntryWithLabel(gtk.HBox):
    
    def __init__(self, label="", visibility = True, maxLength = None):
        gtk.HBox.__init__(self, homogeneous = True, spacing = 20)
        self.__label = gtk.Label(label)
        self.__label.set_justify( gtk.JUSTIFY_LEFT )
        self.__entry = gtk.Entry()
        self.__entry.set_visibility( visibility )
        if maxLength is not None:
            self.__entry.set_max_length(maxLength)
        self.pack_start( self.__label )
        self.pack_start( self.__entry )
    
    # Get text value from entry
    def get_text(self):
        return self.__entry.get_text()
    
    # Set text value of entry
    def set_text(self, text):
        self.__entry.set_text( text )
    
    # Set length of textbox
    def setEntryWidth(self, num):
        self.__entry.set_width_chars( num )
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.