コード例 #1
0
class PyDebugActivity(Activity, TerminalGui, EditorGui, ProjectGui):
    #ipshell = IPShellEmbed()
    MIME_TYPE = 'application/vnd.olpc-sugar'
    DEPRECATED_MIME_TYPE = 'application/vnd.olpc-x-sugar'
    MIME_ZIP = 'application/zip'
    _zipped_extension = '.xo'
    _unzipped_extension = '.activity'
    dirty = False

    #global start_clock

    def __init__(self, handle):
        #handle object contains command line inputs to this activity
        self.handle = handle
        _logger.debug('Activity id:%s.Object id: %s. uri:%s' %
                      (handle.activity_id, handle.object_id, handle.uri))
        self.passed_in_ds_object = None
        if handle.object_id and handle.object_id != '':
            self.passed_in_ds_object = datastore.get(handle.object_id)
            if self.passed_in_ds_object:
                d = self.passed_in_ds_object.metadata
                #log_dict(d,'initial datastore metadata ==>:')
        else:
            ds_object = self.get_new_dsobject()
            if hasattr(ds_object, 'get_object_id'):
                handle.object_id = ds_object.get_object_id()
            else:
                handle.object_id = ds_object.object_id
            _logger.debug(
                'no initial datastore object id passed in via handle')

        #Save a global poiinter so remote procedure calls can communicate with pydebug
        global pydebug_instance
        pydebug_instance = self
        start_clock = time.clock()

        #init variables
        self.make_paths()
        self.save_icon_clicked = False
        self.source_directory = None
        self.data_file = None
        self.help = None
        self.help_x11 = None
        self.dirty = False
        self.sock = None
        #self.last_filename = None
        self.debug_dict = {}
        self.activity_dict = {}
        self.manifest_treeview = None  #set up to recognize an re-display of playpen
        #self.set_title(_('PyDebug Activity'))
        self.ds = None  #datastore pointer
        self._logger = _logger
        self.traceback = 'Context'
        self.abandon_changes = False
        self.delete_after_load = None
        self.find_window = None
        self.icon_outline = 'icon_square'
        self.icon_window = None
        self.last_icon_file = None
        self.activity_data_changed = False
        self.icon_basename = None

        #sugar 0.82 has a different way of getting colors and dies during init unless the following
        self.profile = profile.get_profile()
        self.profile.color = XoColor()

        #get the persistent data across all debug sessions and start using it
        self.get_config()

        #give the server a chance to get started so terminal can connect to it
        self.non_blocking_server()
        #glib.idle_add(self.non_blocking_server)
        """
        if self.request_new_jobject and self.debug_dict.get('jobject_id','') != '':
            self.request_new_jobject = False
    
        #keep on using the same journal entry
        if self.debug_dict.get('jobject_id','') != '':
            handle.object_id = self.debug_dict.get('jobject_id','')
        """

        # init the Classes we are subclassing
        _logger.debug('about to init  superclass activity. Elapsed time: %f'%\
                      (time.clock()-start_clock))
        Activity.__init__(self, handle, create_jobject=False)
        """
        if self.request_new_jobject:
            #check to see if the object was created
            if self._jobject:
                self.debug_dict['jobject_id'] = str(self._jobject.object_id)
            else:
                _logger.debug('failed to create jobject in Activity.__init__')
        """
        self.connect('realize', self.realize_cb)
        self.accelerator = gtk.AccelGroup()
        self.add_accel_group(self.accelerator)

        #set up the PANES for the different functions of the debugger
        _logger.debug('about to set up Menu panes. Elapsed time: %f' %
                      (time.clock() - start_clock))
        self.panes = {}
        PANES = ['TERMINAL', 'EDITOR', 'PROJECT', 'HELP']
        for i in range(len(PANES)):
            self.panes[PANES[i]] = i

        #toolbox needs to be available during init of modules
        self.toolbox = pytoolbar.ActivityToolbox(self)
        self.toolbox.connect_after('current_toolbar_changed',
                                   self._toolbar_changed_cb)
        self.toolbox.set_current_toolbar(self.panes['TERMINAL'])

        #########################################################################################
        #init the sub functions
        TerminalGui.__init__(self, self, self.toolbox)
        EditorGui.__init__(self, self)
        ProjectGui.__init__(self, self)
        self.help = Help(self)
        self.util = Utilities(self)
        #########################################################################################

        #if first time run on this machine, set up home directory
        if not os.path.isfile(os.path.join(self.debugger_home, '.bashrc')):
            self.setup_home_directory()

        # setup the search options
        self.s_opts = SearchOptions(
            where=S_WHERE.file,
            use_regex=False,
            ignore_caps=True,
            replace_all=False,

            #defaults to avoid creating
            #a new SearchOptions object for normal searches
            #should never be changed, just make a copy like:
            #SearchOptions(self.s_opts, forward=False)
            forward=True,
            stay=False)
        self.safe_to_replace = False

        #get the sugar version
        (major, minor, micro, release) = self._activity.util.sugar_version()
        _logger.debug('sugar version major:%s minor:%s micro:%s release:%s' %
                      (major, minor, micro, release))
        if not minor:
            minor = 70
        self.sugar_minor = minor

        #########################################################################################

        _logger.debug(
            'All app objects created. about to set up Display . Elapsed time: %f'
            % (time.clock() - start_clock))
        self.canvas_list = []
        self.canvas_list.append(self._get_terminal_canvas())
        self.canvas_list.append(self._get_edit_canvas())
        self.canvas_list.append(self._get_project_canvas())
        self.canvas_list.append(self._get_help_canvas())

        nb = gtk.Notebook()
        nb.show()
        nb.set_show_tabs(False)

        for c in self.canvas_list:
            nb.append_page(c)
        self.pydebug_notebook = nb

        #the following call to the activity code puts our notebook under the stock toolbar
        self.set_canvas(nb)

        helpbar = self.help.get_help_toolbar()

        self.toolbox.add_toolbar(_('Edit'), self.get_editbar())
        self.toolbox.add_toolbar(_('Project'), self.get_projectbar())
        self.toolbox.add_toolbar(_('Help'), self.help.get_help_toolbar())
        self.set_toolbox(self.toolbox)
        self.toolbox.show()

        #set which PANE is visible initially
        self.set_visible_canvas(self.panes['PROJECT'])
        self.set_toolbar(self.panes['PROJECT'])

        _logger.debug('about to setup_project_page. Elapsed time: %f' %
                      (time.clock() - start_clock))
        self.setup_project_page()
        _logger.debug(
            'about Returned from setup_project_page. Elapsed time: %f' %
            (time.clock() - start_clock))

        #get the journal datastore information and resume previous activity
        #self.metadata = self.ds
        if self.passed_in_ds_object and self.passed_in_ds_object.get_file_path(
        ):
            ds_file = self.passed_in_ds_object.get_file_path()
        else:
            ds_file = ''
        _logger.debug('about to  call read  routine  Elapsed time: %f' %
                      (time.clock() - start_clock))
        self.read_file(ds_file)
        _logger.debug('about  (end of init) Elapsed time: %f' %
                      (time.clock() - start_clock))

    #########################################################################################

    def get_activity_toolbar(self):
        """pass toolbox to subclassed objects"""
        return self.toolbox

    def get_editor(self):
        return self

    def get_accelerator(self):
        """override terminal_gui's method"""
        return self.accelerator

    def realize_cb(self):
        _logger.debug('about total time to realize event: %f' %
                      (time.clock() - start_clock))

    def py_stop(self):
        self.__stop_clicked_cb(None)

    def __stop_clicked_cb(self, button):
        _logger.debug('caught stop clicked call back')
        #threaded_server_close()
        self.help.close_pydoc()
        self.save_all_breakpoints()
        self.close(skip_save=False)

    def non_blocking_server(self):
        start_threaded_server()
        #gobject.idle_add(start_threaded_server)
        #forking_server.main()

    def new_pane(self, funct, i):
        self.panes[PANES[i]] = i
        self.canvas_list.append(funct())
        i += 1
        return i

    def make_paths(self):
        self.pydebug_path = os.environ['SUGAR_BUNDLE_PATH']
        p_path = os.environ['SUGAR_BUNDLE_PATH']
        if os.environ.get("PYTHONPATH", '') == '':
            os.environ['PYTHONPATH'] = self.pydebug_path
        else:
            p_path_list = os.environ['PYTHONPATH'].split(':')
            if not self.pydebug_path in p_path_list:
                os.environ[
                    'PYTHONPATH'] = self.pydebug_path + ':' + os.environ.get(
                        "PYTHONPATH", '')
        _logger.debug('sugar_bundle_path:%s\nsugar_activity_root:%s' %
                      (os.environ['SUGAR_BUNDLE_PATH'],
                       os.environ['SUGAR_ACTIVITY_ROOT']))
        self.debugger_home = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],
                                          'data')
        self.child_path = None
        os.environ["HOME"] = self.debugger_home
        path_list = os.environ['PATH'].split(':')
        new_path = os.path.join(self.pydebug_path, 'bin:')
        if not new_path in path_list:
            os.environ['PATH'] = new_path + os.environ['PATH']
        self.storage = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'],
                                    'data/pydebug')
        self.sugar_bundle_path = os.environ['SUGAR_BUNDLE_PATH']
        self.activity_playpen = os.path.join(self.storage, 'playpen')
        if not os.path.isdir(self.activity_playpen):
            os.makedirs(self.activity_playpen)
        self.hide = os.path.join(self.storage, '.hide')
        if not os.path.isdir(self.hide):
            os.makedirs(self.hide)
        _logger.debug('Set IPYTHONDIR to %s' % self.debugger_home)
        os.environ['IPYTHONDIR'] = self.debugger_home

    def setup_home_directory(self):
        """The directory which Sugar activities have permission to write in"""
        src = os.path.join(self.pydebug_path, 'bin', '.bashrc')
        try:
            shutil.copy(src, self.debugger_home)
        except Exception, e:
            _logger.exception('copy .bashrc exception %r' % e)

        src = os.path.join(self.pydebug_path, 'ipythonrc')
        try:
            shutil.copy(src, self.debugger_home)
        except Exception, e:
            _logger.exception('copy ipthonrc exception %r' % e)