<s> import logging <EOL> import os . path <EOL> from envisage . api import Application , ExtensionPoint <EOL> from pyface . api import GUI , SplashScreen <EOL> from pyface . image_resource import ImageResource <EOL> from pyface . tasks . api import TaskLayout , TaskWindowLayout <EOL> from traits . api import Bool , Callable , Directory , Event , HasStrictTraits , Instance , Int , List , Property , Str , Unicode , Vetoable <EOL> from traits . etsconfig . api import ETSConfig <EOL> from . task_window import TaskWindow <EOL> from . task_window_event import TaskWindowEvent , VetoableTaskWindowEvent <EOL> from envisage . _compat import pickle , STRING_BASE_CLASS <EOL> logger = logging . getLogger ( __name__ ) <EOL> class TasksApplication ( Application ) : <EOL> """<STR_LIT>""" <EOL> TASK_FACTORIES = '<STR_LIT>' <EOL> TASK_EXTENSIONS = '<STR_LIT>' <EOL> active_window = Instance ( TaskWindow ) <EOL> gui = Instance ( GUI ) <EOL> icon = Instance ( ImageResource , allow_none = True ) <EOL> name = Unicode <EOL> splash_screen = Instance ( SplashScreen ) <EOL> state_location = Directory <EOL> task_factories = ExtensionPoint ( id = TASK_FACTORIES ) <EOL> task_extensions = ExtensionPoint ( id = TASK_EXTENSIONS ) <EOL> windows = List ( TaskWindow ) <EOL> window_factory = Callable ( TaskWindow ) <EOL> default_layout = List ( TaskWindowLayout ) <EOL> always_use_default_layout = Bool ( False ) <EOL> application_initialized = Event <EOL> application_exiting = Event <EOL> window_created = Event ( TaskWindowEvent ) <EOL> window_opening = Event ( VetoableTaskWindowEvent ) <EOL> window_opened = Event ( TaskWindowEvent ) <EOL> window_closing = Event ( VetoableTaskWindowEvent ) <EOL> window_closed = Event ( TaskWindowEvent ) <EOL> _explicit_exit = Bool ( False ) <EOL> _state = Instance ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> gui = self . gui <EOL> started = self . start ( ) <EOL> if started : <EOL> self . _create_windows ( ) <EOL> gui . set_trait_later ( self , '<STR_LIT>' , self ) <EOL> gui . start_event_loop ( ) <EOL> return started <EOL> def create_task ( self , id ) : <EOL> """<STR_LIT>""" <EOL> factory = self . _get_task_factory ( id ) <EOL> if factory is None : <EOL> return None <EOL> extensions = [ ext for ext in self . task_extensions <EOL> if ext . task_id == id or not ext . task_id ] <EOL> task = factory . create_with_extensions ( extensions ) <EOL> task . id = factory . id <EOL> return task <EOL> def create_window ( self , layout = None , restore = True , ** traits ) : <EOL> """<STR_LIT>""" <EOL> window = self . window_factory ( application = self , ** traits ) <EOL> window . on_trait_change ( self . _on_window_activated , '<STR_LIT>' ) <EOL> window . on_trait_change ( self . _on_window_opening , '<STR_LIT>' ) <EOL> window . on_trait_change ( self . _on_window_opened , '<STR_LIT>' ) <EOL> window . on_trait_change ( self . _on_window_closing , '<STR_LIT>' ) <EOL> window . on_trait_change ( self . _on_window_closed , '<STR_LIT>' ) <EOL> self . window_created = TaskWindowEvent ( window = window ) <EOL> if layout : <EOL> for task_id in layout . get_tasks ( ) : <EOL> task = self . create_task ( task_id ) <EOL> if task : <EOL> window . add_task ( task ) <EOL> else : <EOL> logger . error ( '<STR_LIT>' , task_id ) <EOL> if restore : <EOL> layout = self . _restore_layout_from_state ( layout ) <EOL> else : <EOL> layout = TaskWindowLayout ( ) <EOL> window . set_window_layout ( layout ) <EOL> return window <EOL> def exit ( self , force = False ) : <EOL> """<STR_LIT>""" <EOL> self . _explicit_exit = True <EOL> try : <EOL> if not force : <EOL> for window in reversed ( self . windows ) : <EOL> window . closing = event = Vetoable ( ) <EOL> if event . veto : <EOL> return False <EOL> self . _prepare_exit ( ) <EOL> for window in reversed ( self . windows ) : <EOL> window . destroy ( ) <EOL> window . closed = True <EOL> finally : <EOL> self . _explicit_exit = False <EOL> return True <EOL> def _create_windows ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _load_state ( ) <EOL> if self . always_use_default_layout or not self . _state . previous_window_layouts : <EOL> window_layouts = self . default_layout <EOL> else : <EOL> window_layouts = self . _state . previous_window_layouts <EOL> for layout in window_layouts : <EOL> for task_id in layout . get_tasks ( ) : <EOL> if not self . _get_task_factory ( task_id ) : <EOL> logger . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % task_id ) <EOL> window_layouts = self . default_layout <EOL> break <EOL> else : <EOL> continue <EOL> break <EOL> for window_layout in window_layouts : <EOL> window = self . create_window ( window_layout , <EOL> restore = self . always_use_default_layout ) <EOL> window . open ( ) <EOL> def _get_task_factory ( self , id ) : <EOL> """<STR_LIT>""" <EOL> for factory in self . task_factories : <EOL> if factory . id == id : <EOL> return factory <EOL> return None <EOL> def _prepare_exit ( self ) : <EOL> """<STR_LIT>""" <EOL> self . application_exiting = self <EOL> self . _save_state ( ) <EOL> def _load_state ( self ) : <EOL> """<STR_LIT>""" <EOL> state = TasksApplicationState ( ) <EOL> filename = os . path . join ( self . state_location , '<STR_LIT>' ) <EOL> if os . path . exists ( filename ) : <EOL> try : <EOL> with open ( filename , '<STR_LIT:r>' ) as f : <EOL> restored_state = pickle . load ( f ) <EOL> if state . version == restored_state . version : <EOL> state = restored_state <EOL> else : <EOL> logger . warn ( '<STR_LIT>' ) <EOL> except : <EOL> logger . exception ( '<STR_LIT>' , <EOL> filename ) <EOL> self . _state = state <EOL> def _restore_layout_from_state ( self , layout ) : <EOL> """<STR_LIT>""" <EOL> match = self . _state . get_equivalent_window_layout ( layout ) <EOL> if match : <EOL> match . active_task = layout . get_active_task ( ) <EOL> layout = match <EOL> else : <EOL> layout = layout . clone_traits ( ) <EOL> for i , item in enumerate ( layout . items ) : <EOL> id = item if isinstance ( item , STRING_BASE_CLASS ) else item . id <EOL> match = self . _state . get_task_layout ( id ) <EOL> if match : <EOL> layout . items [ i ] = match <EOL> return layout <EOL> def _save_state ( self ) : <EOL> """<STR_LIT>""" <EOL> window_layouts = [ w . get_window_layout ( ) for w in self . windows ] <EOL> self . _state . previous_window_layouts = window_layouts <EOL> filename = os . path . join ( self . state_location , '<STR_LIT>' ) <EOL> try : <EOL> with open ( filename , '<STR_LIT:w>' ) as f : <EOL> pickle . dump ( self . _state , f ) <EOL> except : <EOL> logger . exception ( '<STR_LIT>' ) <EOL> def _default_layout_default ( self ) : <EOL> window_layout = TaskWindowLayout ( ) <EOL> if self . task_factories : <EOL> window_layout . items = [ self . task_factories [ <NUM_LIT:0> ] . id ] <EOL> return [ window_layout ] <EOL> def _gui_default ( self ) : <EOL> return GUI ( splash_screen = self . splash_screen ) <EOL> def _state_location_default ( self ) : <EOL> state_location = os . path . join ( ETSConfig . application_home , <EOL> '<STR_LIT>' , ETSConfig . toolkit ) <EOL> if not os . path . exists ( state_location ) : <EOL> os . makedirs ( state_location ) <EOL> logger . debug ( '<STR_LIT>' , state_location ) <EOL> return state_location <EOL> def _on_window_activated ( self , window , trait_name , event ) : <EOL> self . active_window = window <EOL> def _on_window_opening ( self , window , trait_name , event ) : <EOL> self . window_opening = window_event = VetoableTaskWindowEvent ( <EOL> window = window ) <EOL> if window_event . veto : <EOL> event . veto = True <EOL> def _on_window_opened ( self , window , trait_name , event ) : <EOL> self . windows . append ( window ) <EOL> self . window_opened = TaskWindowEvent ( window = window ) <EOL> def _on_window_closing ( self , window , trait_name , event ) : <EOL> self . window_closing = window_event = VetoableTaskWindowEvent ( <EOL> window = window ) <EOL> if window_event . veto : <EOL> event . veto = True <EOL> else : <EOL> window_layout = window . get_window_layout ( ) <EOL> self . _state . push_window_layout ( window_layout ) <EOL> if len ( self . windows ) == <NUM_LIT:1> and not self . _explicit_exit : <EOL> self . _prepare_exit ( ) <EOL> def _on_window_closed ( self , window , trait_name , event ) : <EOL> self . windows . remove ( window ) <EOL> self . window_closed = TaskWindowEvent ( window = window ) <EOL> if len ( self . windows ) == <NUM_LIT:0> : <EOL> self . stop ( ) <EOL> class TasksApplicationState ( HasStrictTraits ) : <EOL> """<STR_LIT>""" <EOL> previous_window_layouts = List ( TaskWindowLayout ) <EOL> window_layouts = List ( TaskWindowLayout ) <EOL> version = Int ( <NUM_LIT:1> ) <EOL> def get_equivalent_window_layout ( self , window_layout ) : <EOL> """<STR_LIT>""" <EOL> for layout in self . window_layouts : <EOL> if layout . is_equivalent_to ( window_layout ) : <EOL> return layout <EOL> return None <EOL> def get_task_layout ( self , task_id ) : <EOL> """<STR_LIT>""" <EOL> for window_layout in self . window_layouts : <EOL> for layout in window_layout . items : <EOL> if layout . id == task_id : <EOL> return layout <EOL> return None <EOL> def push_window_layout ( self , window_layout ) : <EOL> """<STR_LIT>""" <EOL> self . window_layouts = [ layout for layout in self . window_layouts <EOL> if not layout . is_equivalent_to ( window_layout ) ] <EOL> self . window_layouts . insert ( <NUM_LIT:0> , window_layout ) </s>
