How to handle "preset://" in filenames

  • On 02/06/2013 at 03:22, xxxxxxxx wrote:

    I am dragging a Content browser file to a customgui file input.
    However, when I drag e.g. "preset://broadcast.lib4d/Resources/Images/pictures/IMG_0605.jpg" to this field, the input is displayed in the field, but the length is 0.

    I think this has to do again with "preset://".
    Because when I delete that part manual from the input file, the length is >0 (thus ok).

    So, how to handle this sort of filenames?

    GUI part
            self.file = self.AddCustomGui(MY_HDRFILE, c4d.CUSTOMGUI_FILENAME, "", c4d.BFH_SCALEFIT, 0, 0)  
    Input part
            if (id == MY_HDRFILE) :
                hdrfilename = self.GetString(MY_HDRFILE)
                print "hdrfilename: ", hdrfilename, len(hdrfilename)
                return True

  • On 02/06/2013 at 06:44, xxxxxxxx wrote:

    After some more testing, I think, it could en another issue / I'm doing something wrong.
    So, not 'preset://" related, but a functionality issues.

    The thing is, I drag the file to the CUSTOMGUI_FILENAME field.
    And it seems that dragging into the field is not recognized.
    Typing or selecting is ok, but dragging apprently not.

    I used the CUSTOMGUI_FILENAME because I want to drag the to a link field.
    In the normal link field you can only drag objects and materials into the field.

    All I want is to drag a picture from the content browser into my plugin / my linkfield.
    It should be possible. The Material manager is doing it too.

  • On 02/06/2013 at 07:30, xxxxxxxx wrote:

    Call manually GeDialog.Command() with the filename ID in your dialog when you recieve a 
    drag and drop message for your filename gadget.

  • On 02/06/2013 at 08:10, xxxxxxxx wrote:

    Ok, I tried it. See below.
    But (of course?) it started looping.
    I guess this is not what you mean?

        def Command(self, id, msg) :
            print id                     #Prints the ID of the UA
            if (id == 1012) :
                print "file: ", self.GetString (1012)
                self.Command(1012, msg)
                return True

  • On 02/06/2013 at 08:43, xxxxxxxx wrote:

    Not in the Command() , in the Message() method.

    def Message(self, msg, res) :
    	if msg.GetId() == c4d.MSG_DRAGANDDROP:
    		self.Command(c4d.MSG_DRAGANDDROP, c4d.BaseContainer())
    def Command(self, id, msg) :
    	if id == c4d.MSG_DRAGANDDROP:
    		# do something

    Something like this. This will call Command() each time a gadget receives a drag and drop 
    message in your dialog. To only react to a specific gadgets you have to unpack the msg 
    container in the message method and then pass that id to command.

  • On 02/06/2013 at 10:07, xxxxxxxx wrote:

    Here my code.
    What I see:
    - Message never receives a drag&drop id
    "Dragged" is never printed on the console.

    import c4d
    from c4d import bitmaps, gui, plugins, utils
    import collections, os
    ### Dailoog test ###
    # Add / remove GUI fields.
    PLUGIN_ID = 14500110 #TestID only!!!!!!!!!!!!
    class MyDialog(gui.GeDialog) :
        def CreateLayout(self) :
            self.SetTitle("Test Dialoog.")
            settings = c4d.BaseContainer()
            settings.SetBool(c4d.FILENAME_TEXTURE, True)
            settings.SetBool (c4d.DRAGANDDROP_FLAG_MSGVALID, True)		#required?
            self.element = self.AddStaticText(id=1011, flags=c4d.BFH_MASK, initw=150, name="Select Input File:", borderstyle=c4d.BORDER_NONE)
            self.file = self.AddCustomGui(1012, c4d.CUSTOMGUI_FILENAME, "", c4d.BFH_SCALEFIT, 0, 0, settings)
            return True
        def Command(self, id, msg) :
            if (id == 1012) :                               #not working, drag and drop not recognized
                print "file: ", self.GetString (1012)
                return True
            if (id == c4d.MSG_DRAGANDDROP) :
                print "file drag: ", self.GetString (1012)
                return True       
        def Message(self, msg, result) :
            if (msg.GetId() == c4d.MSG_DRAGANDDROP) :
                print "Dragged"
                self.Command(self, 1012, c4d.BaseContainer())  #c4d.MSG_DRAGANDDROP or 1012?
            return gui.GeDialog.Message(self, msg, result)
            return True
    class TestDialoog(plugins.CommandData) :
        dialog = None
        def Execute(self, doc) :
            if self.dialog is None: self.dialog = MyDialog()
            return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=500, defaulth=500)
        def RestoreLayout(self, sec_ref) :
            if self.dialog is None: self.dialog = MyDialog()
            return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
    if __name__ == "__main__":
         bmp = bitmaps.BaseBitmap()
         dir, f = os.path.split(__file__)
         fn = os.path.join(dir, "res", "icon.tif")

  • On 02/06/2013 at 11:04, xxxxxxxx wrote:

    I think the code LD posted is more designed for a Node based plugin. Not a GeDialog.

    I've used the filename gizmo in one of my examples.
    Here's the entire code:

    """  This is an example of using a .res based link box gizmo. And a customgui FILENAME gizmo  """  
    #Id's for the custom LinkBox GUI if needed  
    #CUSTOMGUI_LINKBOX = 1009415,    
    #CUSTOMGUI_INLINE = 300001044,  
    import c4d,os,sys  
    from c4d import plugins, utils, bitmaps, gui, documents  
    Plugin_ID=1000011 # Testing id ONLY!!!!!!!   
    ResBasedMenu =  10001  
    MY_FILE      =  10002  
    MY_LINK      =  10003  
    MY_GROUP     =  10004  
    class MyDialog_Gui(gui.GeDialog) :  
      mylink = None  
      file = None  
      def CreateLayout(self) :      
          res = self.LoadDialogResource(ResBasedMenu)    #Loads GUI stuff from the .res file  
          self.GroupBegin(MY_GROUP, c4d.BFH_SCALEFIT|c4d.BFH_SCALEFIT, 1, 3, "Group Title",0) #id, flags, columns, rows, grouptext, groupflags  
          self.GroupBorderSpace(5, 20, 5, 20) #Left, top, Right, Bottom   
          self.SetTitle("LinkBox Example")    
          self.AddStaticText(1111,c4d.BFH_LEFT,50,10,"input",c4d.BORDER_NONE) #id, flags, height, width, text, borderstyle  
          #A linkbox gizmo created in the .res file  
          self.mylink = self.FindCustomGui(MY_LINK, c4d.CUSTOMGUI_LINKBOX)          
          #A FileName gizmo created here in the code(not in the .res file)  
          settings = c4d.BaseContainer()  
          #settings.SetBool(c4d.FILENAME_DIRECTORY, True)  #Use this to restrict selections to a folder(not a file)  
          #settings.SetBool(c4d.FILENAME_SAVE, True)          #Use this to open the save dialog  
          #settings.SetBool(c4d.FILENAME_TEXTURE, True)    #Texture mode...Makes the "do you want to create a project copy" message window pop up  
          self.file = self.AddCustomGui(MY_FILE, c4d.CUSTOMGUI_FILENAME, "", c4d.BFH_SCALEFIT|c4d.BFV_CENTER, 0, 0, settings)  
          return res      
      def InitValues(self) :   
          return True  
      def Command(self, id, msg) :  
          doc = documents.GetActiveDocument()  
          if id == MY_LINK:                           #When an object is droppped into the linkbox  
               print self.mylink.GetLink().GetName()  #print that object's name      
          return True  
      def CoreMessage(self, id, msg) :      
          if id == c4d.EVMSG_CHANGE:     
              doc = documents.GetActiveDocument()   
              #print "Event Occurred"      
              linkedFile = self.GetString(MY_FILE)   #Gets the fn(string) path of the file in the gizmo  
              if len(linkedFile) != 0:               #If there's a file in the gizmo  
                  print linkedFile                   #Do something with that file  
          return True      
    #   MyDialog_Main --- Where the plugin stuff happens--Don't edit this part  
    class myDialog_Main(plugins.CommandData) :  
      dialog = None  
      def Execute(self, doc) :  
          #Create the dialog  
          if self.dialog is None:  
              self.dialog = MyDialog_Gui()  
          return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=Plugin_ID, xpos=-1, ypos=-1)  
      def RestoreLayout(self, sec_ref) :  
          #Manage the async dialog so it can be docked in the UI  
          if self.dialog is None:  
              self.dialog = MyDialog_Gui()  
          return self.dialog.Restore(pluginid=Plugin_ID, secret=sec_ref)  
    if __name__ == "__main__":  
     path, fn = os.path.split(__file__)  
     #bmp = bitmaps.BaseBitmap()  
     #bmp.InitWith(os.path.join(path, "res/icons/", "None")) #Uses a folder called "icons" inside the "res" folder to hold the icon  
     plugins.RegisterCommandPlugin(Plugin_ID, "LinkBox Example", 0, None, "", myDialog_Main())

    When an image file is added to the filename gizmo using the file browser. The EVMSG_CHANGE message is sent to C4D. So you can use that message in place of a drag&drop message.


  • On 02/06/2013 at 11:10, xxxxxxxx wrote:

    When a msg id does not work / is not received. Simply print all ids and then search after them.
    You can do this in c4d by searching in the c4d __dict__ . Personally i have a small macro in 
    sublime text which produces a agent ransack search string out of the c4d console output (strip 
    everything not a number, kill doubles and connect everything with an OR).

    agent ransack will come up with that for your plugin :

    resource\coffeesymbols.h 173,00 KB 19.04.2013 11:20:42
    5798 BFM_GETCURSORINFO=1667853926,
    5830 BFM_GOTFOCUS=1648838211,
    5831 BFM_LOSTFOCUS=1649165891,
    5870 BFM_ACTION=1648444244,
    5893 BFM_ACTIVE_CHG=1648444231,
    5981 BFM_CORE_MESSAGE=1298360653,
    5994 BFM_INTERACTSTART=1768846433,
    5995 BFM_INTERACTEND=1768846437,
    6028 BFM_FADE_REMOVEALL=1178682437,

    so to fix your plugin you have to do this :

    def Command(self, id, msg) :
            if (id == 1012) :
                print "file: ", self.GetString (1012)
            return True       
        def Message(self, msg, result) :
            if (msg.GetId() == c4d.BFM_ACTION) :
                cid = msg[c4d.BFM_ACTION_ID]
                val = msg[c4d.BFM_ACTION_VALUE]
                print 'Msg ID:', cid, ' Val:', val
                self.SetString(cid, val)
            return gui.GeDialog.Message(self, msg, result)

    edit : and to be extra clear before someone starts complaining, the fixed code is super 
    unsafe due laziness, practically you have to check both the action id and value if they are 
    valid. you could do this by passing it to command().

  • On 02/06/2013 at 11:44, xxxxxxxx wrote:

    Thank you very much.
    Also thanks for the patience.
    I''ll try to do something back, by putting python tutorials on my blog.

    Thanks again. I keep learning good stuff from you and this forum.

Log in to reply