Пример #1
0
    def _on_extras_error(message):
        """ Log an Author's error in source, in the Params

        Don't use proceed(), don't need its stack trace.
        But GimpFu did not fixup user's code so this should be more severe than a warning?
        """
        Deprecation.say("Error in plugin author's source: " + message)
Пример #2
0
 def substitute_empty_string_for_none(self, arg, argname):
     if arg is None:
         Deprecation.say(
             f"Deprecated: Registered {argname} should be empty string, not None"
         )
         result = ""
     else:
         result = arg
     return result
Пример #3
0
 def canonicalize_prefix(cls, proc_name):
     if (not proc_name.startswith("python-")
             and not proc_name.startswith("extension-")
             and not proc_name.startswith("plug-in-")
             and not proc_name.startswith("file-")):
         result = "python-fu-" + proc_name
         message = f"Procedure name canonicalized to {result}"
         Deprecation.say(message)
     else:
         result = proc_name
     return result
Пример #4
0
 def __getitem__(self, key):
     '''
     CRUX:
     If the key is not in the wrapped dictionary, return unmapped key
     If key is in dictionary, return mapped and tell author of deprecated.
     '''
     # TODO implement with except KeyError: would be faster?
     if key in self.__dict__.keys():
         Deprecation.say(f"Deprecated name: {key}")
         return self.__dict__[key]
     else:
         return key
Пример #5
0
    def deriveMissingImageParams(self, metadata):
        '''
        Some plugins declare they are <Image> plugins,
        but don't have first two params equal to (image, drawable),
        and have imagetype == "" (menu item enabled even if no image is open).
        And then Gimp refuses to create procedure
        (but does create an item in pluginrc!)
        E.G. sphere.py

        So we diverge the signature of the plugin from the signature of the run_func.
        The author might be unaware, unless they explore,
        or try to call the PDB procedure from another PDB procedure.

        TODO after we are done, the count of args to run_func
        and the count of formal parameters (PARAMS) should be the same.
        Can we count the formal parameters of run_func?
        '''

        result = False
        # if missing params (never there, or not fixed by earlier patch)
        # TODO if params are missing altogether
        if ( metadata.type == FuProcedureType.Image ) :
            # fix missing image declaration
            if ( (len(self.PARAMS) > 0)
                and self.PARAMS[0].PF_TYPE != PF_IMAGE
                ) :
                # FuFormalParams.logger
                Deprecation.say(f"Missing image param for Image type plugin {self.owner_name}")
                self.PARAMS.insert(0, FuFormalParams.image_param)
                result = True
            if ( (len(self.PARAMS) > 1)
                and self.PARAMS[1].PF_TYPE != PF_DRAWABLE
                ) :
                Deprecation.say("Missing drawable param for Image plugin")
                self.PARAMS.insert(1, FuFormalParams.drawable_param)
                result = True
        return result
Пример #6
0
 def _deriveMissingMenu(self):
     '''
     if menu is not given, derive it from label
     Ability to omit menu is deprecated, so this is FBC.
     '''
     result = False
     if not self.MENUPATH:
         if self.MENUITEMLABEL:
             # label but no menu. Possible menu path in the label.
             fields = self.MENUITEMLABEL.split("/")
             if fields:
                 self.MENUITEMLABEL = fields.pop()
                 self.MENUPATH = "/".join(fields)
                 result = True
                 Deprecation.say(
                     f"Use the 'menu' parameter instead of passing a full menu path in 'label'."
                 )
             else:
                 # 'label' is not a path, can't derive menu path
                 # TODO will GIMP show it in the GUI in a fallback place?
                 Deprecation.say(
                     f"Simple menu item 'label' without 'menu' path.")
         else:
             # no menu and no label
             # Normal, not a deprecation. Plugin only callable by other plugins
             self.logger.debug(
                 f"No 'menu' and no 'label'.  Plugin {self._name} will not appear in Gimp GUI."
             )
     else:
         if self.MENUITEMLABEL:
             # menu and label given
             # Normal, user intends plugin appear in GUI
             pass
         else:
             # menu but no label
             # TODO Gimp will use suffix of 'menu' as 'label' ???
             message = (f" Use the 'label' parameter instead"
                        f"of passing menu item at end of 'menu'.")
             Deprecation.say(message)
     return result
Пример #7
0
    def _fix_deprecated_menu(self):
        """ Fix menu paths deprecated. """
        # require _deriveMissingMenu() called prior

        # Deprecated Since 2.8.
        # No longer the case that they should be in <File>/New as some docs say???
        if self.MENUPATH.startswith("<Toolbox>/Xtns/Languages/Python-Fu"):
            self.MENUPATH = self.MENUPATH.replace(
                "<Toolbox>/Xtns/Languages/Python-Fu",
                "<Image>/Filters/Extensions")
            Deprecation.say(
                "Replaced menu path <Toolbox>/Xtns/Languages/Python-Fu with: <Image>/Filters/Extensions"
            )
        elif self.MENUPATH.startswith("<Toolbox>/Xtns"):
            self.MENUPATH = self.MENUPATH.replace(
                "<Toolbox>/Xtns", "<Image>/Filters/Extensions")
            Deprecation.say(
                "Replaced menu path <Toolbox>/Xtns with: <Image>/Filters/Extensions"
            )
        elif self.MENUPATH.startswith("<Toolbox>"):
            self.MENUPATH = self.MENUPATH.replace("<Toolbox>", "<Image>")
            Deprecation.say("Replaced menu path <Toolbox> with: <Image>")
Пример #8
0
    def deriveMissingParams(self, metadata):
        """ FBC Add missing params according to plugin type.
        Returns True when insert params.
        """

        '''
        FBC.
        In the distant past, an author could specify menu like <Load>
        and not provide a label
        and not provide the first two params,
        in which case GimpFu inserts two params.
        Similarly for other cases.
        '''

        result = False

        # v2 if self.did_fix_menu and plugin_type == PLUGIN:
        # require _deriveMissingMenu called earlier
        if metadata.is_new_style_registration:
            # specified params are explict, requires no fix
            pass
        elif metadata.type == FuProcedureType.Load :
            # insert into slice
            self.PARAMS[0:0] = FuFormalParams.file_params
            Deprecation.say(" Fixing two file params for Load plugin")
            result = True
        elif ( metadata.type == FuProcedureType.Image
             or metadata.type == FuProcedureType.Save) :
            self.PARAMS.insert(0, FuFormalParams.image_param)
            self.PARAMS.insert(1, FuFormalParams.drawable_param)
            Deprecation.say(" Fixing two image params for Image or Save plugin")
            if metadata.type == FuProcedureType.Save:
                self.PARAMS[2:2] = file_params
                Deprecation.say(" Fixing two file params for Save plugin")
            result = True
        #print(self.PARAMS)
        return result
Пример #9
0
 def fix_underbar(cls, proc_name):
     new_proc_name = proc_name.replace('_', '-')
     if (new_proc_name != proc_name):
         Deprecation.say("Underbar in procedure name.")
     return new_proc_name
Пример #10
0
    def _run_procedure_in_mode(procedure, run_mode, image, list_all_args,
                               original_args, data):
        '''
        Understands run_mode.
        Different ways to invoke procedure batch, or interactive.

        Hides run_mode from Authors.
        I.E. their run_func signature does not have run_mode.

        require procedure is-a Gimp.Procedure.
        require original_args is-a Gimp.ValueArray.
        require list_all_args is a list of GValues
        '''
        list_wrapped_args = Marshal.wrap_args(list_all_args)

        # To know the Python name of a Gimp.Procedure method (e.g. gimp_procedure_get_name)
        # see gimp/libgimp/gimpprocedure.h, and then remove the prefix gimp_procedure_
        name = procedure.get_name()

        FuRunner.logger.info(
            f"_run_procedure_in_mode: {name}, {run_mode}, {list_wrapped_args}")
        '''
        list_wrapped_args are one-to-one with formal params.
        list_wrapped_args may include some args that are not guiable (i.e. image, drawable)
        '''

        fuProcedure = FuProcedures.get_by_name(name)

        isBatch = (run_mode == Gimp.RunMode.NONINTERACTIVE)
        '''
        Else so-called interactive mode, with GUI dialog of params.
        Note that the v2 mode RUN_WITH_LAST_VALS is obsolete
        since Gimp 3 persists settings, i.e. actual arg values can be from last invocation.
        If not from last invocation, they are the formal parameter defaults.
        '''

        func = fuProcedure.get_authors_function()
        """
        The ProcedureConfig should have length equal to ????
        original_args is-a GimpValueArray
        """
        # config = FuProcedureConfig(procedure, len(list_wrapped_args)-2 )
        config = FuProcedureConfig(fuProcedure, procedure,
                                   original_args.length())
        config.begin_run(image, run_mode, original_args)

        if isBatch:
            try:
                # invoke func with unpacked args.  Since Python3, apply() gone.
                # TODO is this the correct set of args? E.G. Gimp is handling RUN_WITH_LAST_VALS, etc. ???
                runfunc_result = func(*list_wrapped_args)
                final_result = FuResult.makeSuccess(procedure, runfunc_result)
            except Exception as err:
                # TODO print the Exception type
                err_message = f"In plugin: {name}, function: {func}, Exception: {err}"
                FuRunner.logger.warning(err_message)
                final_result = FuResult.makeException(procedure, err_message)
        else:
            '''
           Not enclosed in try:except: since then you don't get a good traceback.
           Any exceptions in showing a dialog are hard programming errors.
           Any exception in executing the run_func should be shown to user,
           either by calling our own dialog or by calling a Gimp.ErrorDialog (not exist)
           or by passing the exception string back to Gimp.
           '''
            was_canceled, runfunc_result = FuRunner._interact(
                procedure, list_wrapped_args, config)
            if was_canceled:
                final_result = FuResult.makeCancel(procedure)
                config.end_run(Gimp.PDBStatusType.CANCEL)
            else:
                final_result = FuResult.makeSuccess(procedure, runfunc_result)
                config.end_run(Gimp.PDBStatusType.SUCCESS)
            """
           OLD above was enclosed in try
           try:
           except Exception as err:
               '''
               Probably GimpFu module programming error (e.g. bad calls to GTK)
               According to GLib docs, should be a warning, since this is not recoverable.
               But it might be author programming code (e.g. invalid PARAMS)
               '''
               proceed(f"Exception opening plugin dialog: {err}")
               final_result = FuResult.make(Gimp.PDBStatusType.EXECUTION_ERROR, GLib.Error())
           """
        '''
        Make visible any alterations to user created images.
        GimpFu promises to hide the need for this.
        '''
        Gimp.displays_flush()  # !!! Gimp, not gimp

        did_suggest_or_deprecate = Suggest.summarize()
        did_suggest_or_deprecate = did_suggest_or_deprecate or Deprecation.summarize(
        )

        if did_suggest_or_deprecate:
            # TODO make this go to the status bar, not a dialog
            # Gimp.message("See console for suggestions and deprecations.")
            pass

        if summarize_proceed_errors():  # side effect is writing to console
            """ Gimpfu proceeded past earlier exceptions.
            Display GIMP dialog.
            """
            msg = "GimpFu detected errors.  See console for a summary."
            Gimp.message(msg)
            final_result = FuResult.makeException(procedure, msg)

            # Alternatively: raise Exception(msg) but that is confusing to Author

        FuRunner.logger.debug(
            f"Returning from: {name} with result:{final_result}")
        # ensure final_result is type GimpValueArray
        assert isinstance(final_result, Gimp.ValueArray)
        return final_result