Example #1
0
    def initialize(self):
        """
        GUI initialization method
        """
        self.currentlog={
            'filename': None,
            'age': 0,
            'manual': False,
        }
        # Create info bar
        self.setupInfoBar()
        # Tray icon setup
        self.trayicon=TrayIcon('pixmaps/lotroassist.png',self.metadata['APP_NAME'],menu=self.widgets.mnuTrayIcon,action=self.trayIconActivate)
        # Load Application preferences
        self.preferences.load()
        # Move info window
        self.widgets.winInfoBar.move(self.preferences.general.infobarposx,self.preferences.general.infobarposy)
        # Log window setup
        self.setupLogWindow()
        self.setupTextStyles()
        self.widgets.scrConsole.add(self.widgets.txtLog)
        # Show log message for app initialization
        self.logMessage('Initialising LOTROAssist','internal')
        # Set preferences
        self.logMessage('Loading preferences','internal')
        self.setPreferences()
        # Dialog module initialization
        self.dialogs=DialogFactory(self.widgets.winMain)
        # Load Application plugins
        self.logMessage('Initialising Plugin system','internal')
        self.plugins=PluginLoader()
        self.loadPlugins()
        # Add main loop callback
        gobject.timeout_add(self.preferences.log.delay,self.mainLoop,priority=gobject.PRIORITY_LOW)
        # Test
        def validatetext(val):
            if val != 'HOLA':
                return "<b>Error</b> de texto"
            return None
        def validateint(val):
            if int(val) != 10:
                return "<b>Error</b> de entero"
            return None
        def validatebool(val):
            if not bool(val):
                return "<b>Error</b> de booleano"
            return None
        def validatefloat(val):
            if float(val) != 10.10:
                return "<b>Error</b> de float"
            return None
        def validatedate(val):
            from datetime import datetime
            if datetime(2010,10,21)>val:
                return "<b>Error</b> de fecha"
            return None
        self.widgets.dbentTest.add_validators(validatetext,validatebool)
        self.widgets.dbcmbTest.add_validators(validatetext,validatebool)
        self.widgets.dbspnTest.add_validators(validateint,validatefloat)
        self.widgets.dbchkTest.add_validators(validatebool)
        self.widgets.dbreentTest.add_validators(validatetext)
        self.widgets.dbdtpTest.add_validators(validatedate)
        self.widgets.dbcalTest.add_validators(validatedate)

        print 'Entry',self.ui.dbentTest
        print 'ComboBox',self.ui.dbcmbTest
        print 'SpinButton',self.ui.dbspnTest
        print 'CheckButton',self.ui.dbchkTest
        print 'RegExpEntry',self.ui.dbreentTest
        print 'DatePicker',self.ui.dbdtpTest
        print 'Calendar',self.ui.dbcalTest
Example #2
0
    def __init__(self,guifiles=[],configfile=None,mainapp=True,env=None,controlled_quit=True,dialogs=True,splash=True,debug=False,localedir='locale',pixmapsdir='pixmaps',disablenotifsys=False,forceinternalnotifsys=False,**kwargs):
        """
        Class constructor
        """
        # Setting up variables
        self.__guifiles=guifiles
        self.__main_app=mainapp
        self.__debug=debug
        self.__splashscreen=None

        self.APP_DIR=os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe().f_back)))
        self.PIXMAPS_DIR=self.APP_DIR + '/' + pixmapsdir
        self.LOCALE_DIR=self.APP_DIR + '/' + localedir
        # Main app initialization
        if mainapp:
            # Setup glib application name
            glib.set_application_name(self.metadata['APP_CODENAME'])
            # Set up exception handler if this is the main app
            self.excepthandler=_ExceptionHandler(catch_all=debug)
            # If controlled quit is enabled set a handler
            self.excepthandler.set_handler(KeyboardInterrupt,self.__control_c_handler)
            
            # Initialize notifications system
            if disablenotifsys:
                # No graphical notifications system. Fallback to dummy notification system
                self.notifsys=notifsystem.DummyNotificationSystem(self.metadata['APP_NAME'])
            else:
                if not forceinternalnotifsys and evogtk.HAS_PYNOTIFY:
                    # Use PyNotify as notification system
                    self.notifsys=notifsystem.PyNotifyNotificationSystem(self.metadata['APP_NAME'])
                else:
                    # Use internal notification system
                    self.notifsys=notifsystem.NotificationSystem(self.metadata['APP_NAME'])
            if splash:
                self.show_splash()
        # Create GtkBuilder instance
        self.__builder_instance=gtk.Builder()
        # Setup internationalization
        gettext.textdomain(self.metadata['APP_CODENAME'])
        gettext.bindtextdomain(self.metadata['APP_CODENAME'], self.LOCALE_DIR)
        gtk.glade.bindtextdomain(self.metadata['APP_CODENAME'], self.LOCALE_DIR)
        gtk.glade.textdomain(self.metadata['APP_CODENAME'])
        
        self.__builder_instance.set_translation_domain(self.metadata['APP_CODENAME'])

        # Load GUI files
        for guifile in guifiles:
            self.__builder_instance.add_from_file(self.APP_DIR + '/' + guifile)
        # Prepare widgets for easy access
        self.widgets=GUIWidgets(self.__builder_instance)
        # Load default widget access shortcuts
        self.ui=WidgetAccess(self.widgets)
        # Connect GUI signals
        self.__connect_signals()
        # Load shortcuts helper
        self.shortcuts=ShortcutsHelper(self)
        # Set application environment
        if env:
            self.set_environment(env)
        # Create preferences helper if needed
        if self.metadata.has_key('APP_PREFERENCES'):
            self.preferences=_PreferencesHelper(self.metadata['APP_PREFERENCES'],'%s/settings.conf' % self.metadata['APP_NAME'],self.ui)
            # Load Application preferences
            self.preferences.load()
        else:
            self.preferences=None
        # Load current icon theme
        self.icon_theme=gtk.icon_theme_get_default()
        # Set current task mode to unknown
        self.__current_task_mode=None
        # Set class as initialized
        self.__initialised=True
        self.__quit=False
        # Dialog module initialization
        if dialogs:
            self.dialogs=DialogFactory(self,self.widgets.winMain)
        # Call application initialization method passing extra parameters
        self.initialize(**kwargs)
Example #3
0
class LOTROAssistClass(GUIClass):
    """
    LOTROAssist main class
    """
    # Application metadata
    metadata={
        'APP_NAME': 'LOTROAssist',
        'APP_CODENAME': 'lotroassist',
        'APP_VERSION': '0.1',
        'APP_DESC': 'Lord Of The Rings Online Assistant Application',
        'APP_COPYRIGHT': '(C) 2010 Oliver Gutiérrez <*****@*****.**>',
        'APP_WEBSITE': 'http://www.evosistemas.com',
        'APP_PREFERENCES': {
            'general': {
                'closetotray': ('bool',['chkCloseToTray'],True),
                'alwaysshowtrayicon': ('bool',['chkAlwaysShowTrayIcon'],True),
                'shownotifications': ('bool',['chkShowNotifications'],True),
                'datadir': ('str',['fcbDataDir'],'./'),
                'monitorlogs': ('bool',['tactMonitorLogs'],False),
                'showinfobar': ('bool',['tactShowInfoBar'],False),           
                'showconsole': ('bool',['tactShowConsole'],False),
                'infobarposx': ('int',[],0),
                'infobarposy': ('int',[],0),
            },
            'log': {
                'forcesimplelog': ('bool',['chkForceSimpleLog'],False),
                'delay': ('int',['spnLogDelay'],20),
                'normalcolor': ('str',['cbNormalColor'],'#000000'),
                'internalcolor': ('str',['cbInternalColor'],'#00FF00'),
                'logopencolor': ('str',['cbLogOpenColor'],'#0000FF'),
                'plugincolor': ('str',['cbPluginColor'],'#FF0000'),
            },
        }
    }

    def initialize(self):
        """
        GUI initialization method
        """
        self.currentlog={
            'filename': None,
            'age': 0,
            'manual': False,
        }
        # Create info bar
        self.setupInfoBar()
        # Tray icon setup
        self.trayicon=TrayIcon('pixmaps/lotroassist.png',self.metadata['APP_NAME'],menu=self.widgets.mnuTrayIcon,action=self.trayIconActivate)
        # Load Application preferences
        self.preferences.load()
        # Move info window
        self.widgets.winInfoBar.move(self.preferences.general.infobarposx,self.preferences.general.infobarposy)
        # Log window setup
        self.setupLogWindow()
        self.setupTextStyles()
        self.widgets.scrConsole.add(self.widgets.txtLog)
        # Show log message for app initialization
        self.logMessage('Initialising LOTROAssist','internal')
        # Set preferences
        self.logMessage('Loading preferences','internal')
        self.setPreferences()
        # Dialog module initialization
        self.dialogs=DialogFactory(self.widgets.winMain)
        # Load Application plugins
        self.logMessage('Initialising Plugin system','internal')
        self.plugins=PluginLoader()
        self.loadPlugins()
        # Add main loop callback
        gobject.timeout_add(self.preferences.log.delay,self.mainLoop,priority=gobject.PRIORITY_LOW)
        # Test
        def validatetext(val):
            if val != 'HOLA':
                return "<b>Error</b> de texto"
            return None
        def validateint(val):
            if int(val) != 10:
                return "<b>Error</b> de entero"
            return None
        def validatebool(val):
            if not bool(val):
                return "<b>Error</b> de booleano"
            return None
        def validatefloat(val):
            if float(val) != 10.10:
                return "<b>Error</b> de float"
            return None
        def validatedate(val):
            from datetime import datetime
            if datetime(2010,10,21)>val:
                return "<b>Error</b> de fecha"
            return None
        self.widgets.dbentTest.add_validators(validatetext,validatebool)
        self.widgets.dbcmbTest.add_validators(validatetext,validatebool)
        self.widgets.dbspnTest.add_validators(validateint,validatefloat)
        self.widgets.dbchkTest.add_validators(validatebool)
        self.widgets.dbreentTest.add_validators(validatetext)
        self.widgets.dbdtpTest.add_validators(validatedate)
        self.widgets.dbcalTest.add_validators(validatedate)

        print 'Entry',self.ui.dbentTest
        print 'ComboBox',self.ui.dbcmbTest
        print 'SpinButton',self.ui.dbspnTest
        print 'CheckButton',self.ui.dbchkTest
        print 'RegExpEntry',self.ui.dbreentTest
        print 'DatePicker',self.ui.dbdtpTest
        print 'Calendar',self.ui.dbcalTest
        
    def setupInfoBar(self):
        """
        Setups the information bar
        """
        infobar=FloatingWindow(title='LOTROAssist info bar',color='#999',rounded=True,alwaysontop=True,dragable=True,maximize=evogtk.MAXIMIZE_HORIZONTAL)
        hbxinfobar=gtk.HBox(spacing=5)
        infobar.add(hbxinfobar)
        # Add info bar to widget access
        self.widgets.add_widget(infobar,'winInfoBar')
        self.widgets.add_widget(hbxinfobar,'hbxInfoBar')

    def setupLogWindow(self):
        """
        Setup the log window
        """
        # Check if we use GTK Sourceview for log widget
        if evogtk.EVOGTK_HAS_GTKSOURCEVIEW and not self.preferences.log.forcesimplelog:
            # Use GTK Sourceview
            import gtksourceview2
            buffer=gtksourceview2.Buffer()
            view=gtksourceview2.View(buffer)
            view.set_show_line_numbers(True)
            view.set_show_line_marks(True)
        else:
            # Use GTK TextView
            buffer=gtk.TextBuffer()
            view=gtk.TextView(buffer)
        # Show log view and set basic parameters
        self.widgets.add_widget(view,'txtLog')
        view.set_editable(False)
        view.set_cursor_visible(False)
        view.show()
    
    def setupTextStyles(self):
        """
        Setup text styles used by application
        """
        buffer=self.widgets.txtLog.get_buffer()
        tools.newTextTag({'name': 'normal','foreground': self.preferences.log.normalcolor},buffer)
        tools.newTextTag({'name': 'internal','foreground': self.preferences.log.internalcolor, 'weight': 700},buffer)
        tools.newTextTag({'name': 'logopen','foreground': self.preferences.log.logopencolor, 'weight': 700},buffer)
        tools.newTextTag({'name': 'plugin','foreground': self.preferences.log.plugincolor, 'weight': 700},buffer)
    
    def openLogFile(self,widget):
        """
        Manually select the logfile to load
        """
        # Open file selection dialog
        logfile=self.dialogs.fileSelDialog('open','Log File Selection',False,self.preferences.general.datadir)
        # Check if has selected a log file
        if logfile[0]:
            logfile=logfile[0][0]
            self.currentlog={
                'filename': logfile,
                'age': 0,
                'fd': open(logfile,'r'),
                'manual': True,
            }
            # Show desktop notification
            self.showNotification('Opening selected log: %s' % logfile,True)
            self.logMessage('Opened Log File: %s' % logfile,'logopen')
            self.ui.tlbtMonitorLogs=False
            # Do a burst read of log
            self.burstRead()

    
    def quitApplication(self,widget,event=None):
        """
        Application quit callback
        """
        if self.preferences.general.closetotray and widget == self.widgets.winMain:
            self.trayIconActivate()
        else:
            if self.dialogs.msgDialog('¿Do you want to exit LOTRO Assist?', 'question'):
                self.savePreferences()
                self.unloadPlugins()
                self.quit()
        return True
    
    def showPreferences(self,widget=None):
        """
        Show preferences dialog
        """
        self.widgets.winPreferences.show()
        
    def showAbout(self,widget=None):
        """
        Show about dialog
        """
        self.dialogs.aboutDialog(self.metadata)
    
    def trayIconActivate(self,widget=None):
        """
        Toggles main window visible status
        """
        if self.widgets.winMain.get_property('visible'):
            self.widgets.winMain.hide()
            self.trayicon.show()
        else:
            self.widgets.winMain.show()
            self.trayicon.set_visible(self.preferences.general.alwaysshowtrayicon)
    
    def savePreferences(self,widget=None,other=None):
        """
        Save application preferences
        """
        self.widgets.winPreferences.hide()
        self.preferences.general.infobarposx,self.preferences.general.infobarposy=self.widgets.winInfoBar.get_position()
        self.preferences.save()
        self.setPreferences()
        return True

    def setPreferences(self):
        """
        Set preferences
        """
        # Tray Icon preferences
        self.trayicon.set_visible(self.preferences.general.alwaysshowtrayicon)

    def mainLoop(self):
        """
        Starts main log process loop
        """
        # Check if a new log has been created
        if self.ui.tlbtMonitorLogs:
            self.checkLogFiles()
        if self.currentlog.has_key('fd'):
            # Check new lines in current log
            line=self.currentlog['fd'].readline().strip()    
            if line:
                # Call new line callback
                self.newLogLine(line)
        # Return true for loop repeat
        return True
    
    def toggleConsole(self,widget,event=None):
        """
        Toggle log monitoring
        """
        if widget==self.widgets.winConsole:
            self.preferences.general.showconsole=False
        else:
            self.preferences.general.showconsole=widget.get_active()
        if self.preferences.general.showconsole:
            self.widgets.winConsole.show()
        else:
            self.widgets.winConsole.hide()
        return True

    def toggleInfoBar(self,widget,event=None):
        """
        Toggle log monitoring
        """
        if widget==self.widgets.winInfoBar:
            self.preferences.general.showinfobar=False
        else:
            self.preferences.general.showinfobar=widget.get_active()
        if self.preferences.general.showinfobar:
            self.widgets.winInfoBar.show_all()
        else:
            self.widgets.winInfoBar.hide()
        return True

    def toggleMonitorLogs(self,widget):
        """
        Toggle log monitoring
        """ 
        self.preferences.general.monitorlogs=widget.get_active()
        self.currentlog['manual']=not self.preferences.general.monitorlogs
    
    def checkLogFiles(self):
        """
        Check if new log files has been created and replaces current by the new one
        """
        logage=self.currentlog['age']
        logfile=self.currentlog['filename']
        # Get last log filename
        files=os.listdir(self.preferences.general.datadir)
        for file in files:
            filename=file.split('.')
            if len(filename)==2 and filename[1]=='txt':
                fileage=os.stat('%s/%s' % (self.preferences.general.datadir,file))[8]
                if logage<=fileage:
                    logfile='%s/%s' % (self.preferences.general.datadir,file)
                    logage=fileage
        # Check if current log is the newest one
        if logfile != self.currentlog['filename']:
            # Close older log and open the new one
            if self.currentlog.has_key('fd'):
                self.currentlog['fd'].close()
            self.currentlog={
                'filename': logfile,
                'age': logage,
                'fd': open(logfile,'r'),
                'manual': False,
            }
            # Show desktop notification
            self.showNotification('Opened Log File: %s' % logfile,True)
            self.logMessage('Opened Log File: %s' % logfile,'logopen')
            # Do a burst read of log
            self.burstRead()

    def burstRead(self):
        """
        Burst read of a log file
        """
        notif=self.preferences.general.shownotifications
        self.preferences.general.shownotifications=False
        self.logMessage('Doing burst read of lofgile %s' % self.currentlog['filename'],'internal')
        lines=self.currentlog['fd'].readlines()
        for line in lines:
            tools.processPendingEvents()
            self.newLogLine(line.strip(),burst=True)
        self.preferences.general.shownotifications=notif
        self.logMessage('Burst read of lofgile %s finished for a total of %s lines' % (self.currentlog['filename'],len(lines)),'internal')

    
    def showNotification(self,msg,statusbar=False,icon=None):
        """
        Show notification
        """
        if statusbar:
            self.ui.stbMain=msg
        if self.preferences.general.shownotifications:
            self.trayicon.blink()
            self.notifsys.queue_msg(msg=msg,color='#444444',icon=icon)
    
    def logMessage(self,msg,tag='normal'):
        """
        Log Message function
        """
        # TODO: lotroassist: limit log buffer to X lines/bytes
        logbuffer=self.widgets.txtLog.get_buffer()
        iter=logbuffer.get_end_iter()
        logbuffer.insert_with_tags_by_name(iter,msg + '\n', tag)
        iter=logbuffer.get_end_iter()
        self.widgets.txtLog.scroll_to_iter(iter,0)
    
    def newLogLine(self,line,burst=False):
        """
        New line callback
        """
        # Pass the line to plugins
        for plugin in self.plugins.loaded_plugins():
            result=self.plugins.get_plugin_instance(plugin).newLine(line)
            if result and evogtk.EVOGTK_HAS_GTKSOURCEVIEW:
                # TODO: lotroassist: Line marking with custom icons in log
                pass
        # Add line to main log window
        if not burst:
            self.logMessage(line)
        
    def loadPlugins(self):
        """
        Load plugins
        """
        self.logMessage('Loading plugins','internal')
        pluginlist=self.plugins.plugin_list()
        self.logMessage('Found %s plugins' % len(pluginlist),'plugin')
        for plugin in pluginlist:
            self.plugins.load_plugin(plugin,env={'maingui':self})
            # Add plugin to interface if needed
            pluginclass=self.plugins.get_plugin_instance(plugin)
            if pluginclass.metadata.has_key('PLUGIN_DOCK'):
                pluginclass.widgets.vbxMain.unparent()
                pluginlabel=gtk.Label(pluginclass.metadata['PLUGIN_NAME'])
                if pluginclass.metadata['PLUGIN_DOCK']=='main':
                    self.widgets.ntbMain.append_page(pluginclass.widgets.vbxMain,pluginlabel)
                elif pluginclass.metadata['PLUGIN_DOCK']=='lists':
                    self.widgets.ntbLists.append_page(pluginclass.widgets.vbxMain,pluginlabel)
                elif pluginclass.metadata['PLUGIN_DOCK']=='console':
                    self.widgets.ntbConsole.append_page(pluginclass.widgets.vbxMain,pluginlabel)
                elif pluginclass.metadata['PLUGIN_DOCK']=='status':
                    self.widgets.hbxInfoBar.pack_end(pluginclass.widgets.vbxMain,False,False)
                else:
                    raise Exception('Plugin %s have no position for GUI docking' % plugin)
            self.logMessage('\tPlugin %s v%s initialized' % (pluginclass.metadata['PLUGIN_NAME'],pluginclass.metadata['PLUGIN_VERSION']),'plugin')
    
    def unloadPlugins(self):
        """
        Unload Plugins
        """
        for plugin in self.plugins.loaded_plugins():
            self.plugins.unload_plugin(plugin)
Example #4
0
class GUIClass(object):
    """
    **GUI helper base class**
    
    *This class will allow you to start the application*
            
    .. note:: You always want to subclass this class. There are some methods you would like to
        redefine such as initialize

        .. code-block:: python
            :emphasize-lines: 1,2
            
            class MyAppClass(GUIClass):
                pass
    """

    # Application metadata
    metadata={
        'APP_NAME': 'EVOGTK Project',
        'APP_CODENAME': 'evogtkproject',
        'APP_VERSION': '1.0',
        'APP_DESC': 'EVOGTK application project',
        'APP_COPYRIGHT': '(C) 2010 Oliver Gutiérrez <*****@*****.**>',
        'APP_WEBSITE': 'http://www.evosistemas.com',
    }

    # Task modes
    TASKS_MODES={
        evogtk.TASK_MODE_INITIAL: {
            'enable': [],
            'disable': [],
            'show': [],
            'hide': [],
            'activate': [],
            'deactivate': [],
            'callback': None
        },
    }

    def __init__(self,guifiles=[],configfile=None,mainapp=True,env=None,controlled_quit=True,dialogs=True,splash=True,debug=False,localedir='locale',pixmapsdir='pixmaps',disablenotifsys=False,forceinternalnotifsys=False,**kwargs):
        """
        Class constructor
        """
        # Setting up variables
        self.__guifiles=guifiles
        self.__main_app=mainapp
        self.__debug=debug
        self.__splashscreen=None

        self.APP_DIR=os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe().f_back)))
        self.PIXMAPS_DIR=self.APP_DIR + '/' + pixmapsdir
        self.LOCALE_DIR=self.APP_DIR + '/' + localedir
        # Main app initialization
        if mainapp:
            # Setup glib application name
            glib.set_application_name(self.metadata['APP_CODENAME'])
            # Set up exception handler if this is the main app
            self.excepthandler=_ExceptionHandler(catch_all=debug)
            # If controlled quit is enabled set a handler
            self.excepthandler.set_handler(KeyboardInterrupt,self.__control_c_handler)
            
            # Initialize notifications system
            if disablenotifsys:
                # No graphical notifications system. Fallback to dummy notification system
                self.notifsys=notifsystem.DummyNotificationSystem(self.metadata['APP_NAME'])
            else:
                if not forceinternalnotifsys and evogtk.HAS_PYNOTIFY:
                    # Use PyNotify as notification system
                    self.notifsys=notifsystem.PyNotifyNotificationSystem(self.metadata['APP_NAME'])
                else:
                    # Use internal notification system
                    self.notifsys=notifsystem.NotificationSystem(self.metadata['APP_NAME'])
            if splash:
                self.show_splash()
        # Create GtkBuilder instance
        self.__builder_instance=gtk.Builder()
        # Setup internationalization
        gettext.textdomain(self.metadata['APP_CODENAME'])
        gettext.bindtextdomain(self.metadata['APP_CODENAME'], self.LOCALE_DIR)
        gtk.glade.bindtextdomain(self.metadata['APP_CODENAME'], self.LOCALE_DIR)
        gtk.glade.textdomain(self.metadata['APP_CODENAME'])
        
        self.__builder_instance.set_translation_domain(self.metadata['APP_CODENAME'])

        # Load GUI files
        for guifile in guifiles:
            self.__builder_instance.add_from_file(self.APP_DIR + '/' + guifile)
        # Prepare widgets for easy access
        self.widgets=GUIWidgets(self.__builder_instance)
        # Load default widget access shortcuts
        self.ui=WidgetAccess(self.widgets)
        # Connect GUI signals
        self.__connect_signals()
        # Load shortcuts helper
        self.shortcuts=ShortcutsHelper(self)
        # Set application environment
        if env:
            self.set_environment(env)
        # Create preferences helper if needed
        if self.metadata.has_key('APP_PREFERENCES'):
            self.preferences=_PreferencesHelper(self.metadata['APP_PREFERENCES'],'%s/settings.conf' % self.metadata['APP_NAME'],self.ui)
            # Load Application preferences
            self.preferences.load()
        else:
            self.preferences=None
        # Load current icon theme
        self.icon_theme=gtk.icon_theme_get_default()
        # Set current task mode to unknown
        self.__current_task_mode=None
        # Set class as initialized
        self.__initialised=True
        self.__quit=False
        # Dialog module initialization
        if dialogs:
            self.dialogs=DialogFactory(self,self.widgets.winMain)
        # Call application initialization method passing extra parameters
        self.initialize(**kwargs)

    def __setattr__(self,name,value):
        """
        Set attribute method overload for protecting of class specific attributes
        """
        # Check if we are trying to set a protected property
        if name not in ['widgets','ui','preferences','__notifications'] or not self.__dict__.has_key('_GUIClass__initialised'):
            return super(GUIClass,self).__setattr__(name,value)
        else:
            raise Exception(_('EVOGTK: Setting to %s property is not allowed') % name)

    def __connect_signals(self):
        """
        Connects the GUI signals
        """
        # Add default handlers to callbacks
        defaulthandlerlist=['gtk_widget_show','gtk_widget_hide','gtk_widget_grab_focus','gtk_widget_destroy','gtk_true','gtk_false','gtk_main_quit']
        for handler in defaulthandlerlist:
            if not vars(self).has_key(handler):
                vars(self)[handler]=vars(defaulthandlers)[handler]
        # Connect signals
        self.__builder_instance.connect_signals(self)

    def __control_c_handler(self,*args,**kwargs):
        """
        Catches when the user uses Ctrl+C to finish application and launchs the quit method
        """
        self.quit(userbreak=True)

    def show_splash(self,splashimg='splash.png',seconds=3):
        """
        Shows an splash screen using an image
        """
        if not self.__debug:
            splash=gtk.Window(type=gtk.WINDOW_POPUP)
            splash.set_resizable(False)
            splash.set_keep_above(True)
            splash.set_position(gtk.WIN_POS_CENTER)
            splash.add(gtk.image_new_from_file(self.PIXMAPS_DIR + '/' + splashimg))
            splash.show_all()
            self.__splashscreen=(splash,seconds)

    def hide_splash(self,callback=None):
        """
        Hides the splash screen
        """
        if self.__splashscreen:
            self.__splashscreen[0].destroy()
            if callback:
                callback()

    def show_mainwindow(self,window):
        """
        Show main window ant take care about splash screen hiding
        """
        if self.__debug:
            window.show()
        else:
            gobject.timeout_add_seconds(self.__splashscreen[1],self.hide_splash,window.show)

    def set_gui_task(self,mode):
        """
        Setups GUI for an specified task
        """
        if self.TASKS_MODES.has_key(mode):
            self.__current_task_mode=mode
            task=self.TASKS_MODES[mode]
            # Disable widgets
            for widget in task['disable']:
                self.widgets.get_widget(widget).set_sensitive(False)
            # Hide widgets
            for widget in task['hide']:
                self.widgets.get_widget(widget).hide()
            # Enable widgets
            for widget in task['enable']:
                self.widgets.get_widget(widget).set_sensitive(True)
            # Show widgets
            for widget in task['show']:
                self.widgets.get_widget(widget).show()
            # Activate widgets
            for widget in task['activate']:
                self.widgets.get_widget(widget).set_active(True)
            # Deactivate widgets
            for widget in task['deactivate']:
                self.widgets.get_widget(widget).set_active(False)
            # Call specific callback
            if task['callback']:
                getattr(self,task['callback'])()
        else:
            raise Exception(_('EVOGTK: Trying to setup unspecified GUI task mode: %s') % mode)

    def get_gui_task(self):
        """
        Returns current GUI task mode
        """
        return self.__current_task_mode

    def initialize(self):
        """
        Dummy initialize method for application
        """
        pass

    def set_environment(self,env,strict=True):
        """
        Set application environment if needed
        """
        for var in env:
            if self.__dict__.has_key(var):
                if not strict:
                    print _('EVOGTK: Setting member %s from environment initialization to an already set property or method') % var
                if strict:
                    raise Exception(_('EVOGTK: Setting member %s from environment initialization to an already set property or method') % var)
            elif var in ['widgets','ui','preferences','trayicon','notify']:
                raise Exception(_('EVOGTK: Setting varable %s from environment initialization to a protected property is not allowed') % var)       
            self.__dict__[var]=env[var]

    def run(self):
        """
        Launch main application loop
        """
        if self.__main_app:
            EVOGTK_SETTINGS=gtk.settings_get_default()
            EVOGTK_SETTINGS.set_property('gtk-button-images',True)
            gtk.main()
        else:
            raise Exception(_('EVOGTK: Trying to run an application that is not a main application'))

    def quit(self,userbreak=False,status=0):
        """
        Finish application
        
        :param userbreak: Allow user to use Ctrl-C to finish application
        :type userbreak: bool
        :param status: Specifies which status code is returned on application quit
        :type status: int
        
        .. warning:: This method will try to quit application, and will wait for all threads to finish.
            So if you have threads working, application will remain stopped while waiting. 
        """
        # Call application unload callback
        self.unload()
        # Quit application
        if not self.__quit:
            self.__quit=(True,userbreak)
            # Check if there are pending tasks
            if self.__main_app and threadtasks.pending_tasks()>1:
                # Generate the progress bar
                align=gtk.Alignment(xalign=0.5, yalign=0.5, xscale=1, yscale=1)
                align.set_padding(25,25,25,25)
                progress=gtk.ProgressBar()
                progress.set_text(_('Waiting for pending tasks to finish'))
                align.add(progress)
                # Callback for not quit until all pending tasks are finished
                def wait_for_tasks(progress):
                    if threadtasks.pending_tasks()==1:
                        if gtk.main_level():
                            gtk.main_quit()
                        sys.exit(status)
                    progress.pulse()
                    return True
                # Set all widgets to insensitive status
                self.widgets.disable_toplevels()
                # Callback for timeout on waiting for tasks
                gobject.timeout_add(100,wait_for_tasks,progress,priority=gobject.PRIORITY_HIGH)
                # Launch a permanent notification
                if self.notifsys:
                    self.notifsys.queue_custom(align,permanent=True)                
                # If the user used CTRL+C to quit, show message and run gtk loop to make application responsive
                if userbreak:
                    print _('EVOGTK: Finishing tasks, please wait or press CTRL+C again to finish')
                    gtk.main()
            elif self.__main_app:
                if gtk.main_level():
                    gtk.main_quit()
                sys.exit(status)
        else:
            if not self.__quit[1]:
                print _('EVOGTK: Finishing tasks, please wait or press CTRL+C again to finish')
                gtk.main()

    def unload(self):
        """
        Dummy cleanup method for application finish
        
        .. note:: This method should be overloaded mostly for use in plugins
        """
        pass
    
    def debug_status(self):
        """
        Returns debug setting
        """
        return self.__debug
    
    #===========================================================================
    # Default application event handlers
    #===========================================================================

    def showAbout(self,widget=None):
        """
        Show default about dialog
        """
        self.dialogs.aboutDialog(self.metadata)
        return True

    def quitApplication(self,widget,event=None):
        """
        Show default quit dialog
        """
        if self.dialogs.msgDialog(_('¿Do you want to exit %s?') % self.metadata['APP_NAME'], 'question',default=gtk.RESPONSE_NO):
            self.savePreferences()
            self.quit()
        return True

    def showPreferences(self,widget=None):
        """
        Show preferences dialog
        """
        if self.widgets.widget_exists('winPreferences'):
            if self.dialogs.openDialog(self.widgets.winPreferences, close=True)==1:
                self.savePreferences()

    def savePreferences(self,widget=None):
        """
        Save application preferences
        """
        if self.preferences:
            self.preferences.save()
        return True