Saving the Current Document

On 24/10/2014 at 10:17, xxxxxxxx wrote:

Hi,

Any tips on how to prompt the user to save the current document, and then make the saved document the active document?

This is what I'm currently doing:

  
def main() :   
    c4d.StopAllThreads()   
  
    if is_file_saved(doc) :   
        print doc.GetDocumentName() + " was saved."   
    else:   
        c4d.gui.MessageDialog("This document has not been previously saved, please save it now.")   
        default_filename = "SHOW_SEQ_Shot01_vA01.c4d"   
        doc_was_saved = c4d.documents.SaveDocument(doc, default_filename, saveflags=c4d.SAVEDOCUMENTFLAGS_0,   
                                   format=c4d.FORMAT_C4DEXPORT)   
        if doc_was_saved:   
            print "Document was successfully saved."   
        else:   
            print "Document failed to save."   
            return   

This will open up a save dialog, and allow the user to rename the file and save it where they want. However, after the document has been saved, the current document is still named "Untitled 1" or something to that effect. Some questions:

1. How do I save the current file, and ensure that the saved file becomes the working file as opposed to the default "Save As..." / Make-a-copy behavior that seems to be occurring?
2. Assuming #1 isn't possible, how do I retrieve the name/path of the document the user has saved so that I can kill the current doc and load the saved version?

Thanks,

Donovan

On 24/10/2014 at 11:39, xxxxxxxx wrote:

Okay, it feels a little hacky (I hate using CallCommand), but this is my solution:

  
def is_file_saved(doc) :   
    """Determines whether `doc` has been previously saved.   
    Returns `True` if saved, otherwise `False`"""   
  
    #Ensure there's a document   
    if (doc is None) or (not doc.IsAlive()) :   
        return False   
  
    #See if the document has been saved   
    doc_path = doc.GetDocumentPath()   
    if (doc_path is None) or (doc_path == "") :   
        return False   
  
    #The doc exists and has a name, return True   
    return True   
  
def save_document(doc, file_name="SHOW_SEQ_Shot01_vA01.c4d") :   
    """Prompt user to save document. Returns `True` if saved, or `False` if the file wasn't saved."""   
  
    doc.SetDocumentName(file_name)   
    c4d.gui.MessageDialog("This document has not been previously saved, please save it now.")   
    c4d.CallCommand(12098) #Save Current Document   
  
    return is_file_saved(doc)   

On 24/10/2014 at 12:19, xxxxxxxx wrote:

Hi

if you don´t like it hacky, you might use this solution:

  
import c4d,os  
from c4d import gui  
  
  
  
def is_file_saved(doc) :  
  doc = c4d.documents.GetActiveDocument()  
  if doc.GetDocumentPath() != "" :  
      return True  
  
  
  
def main() :  
  
  c4d.StopAllThreads()  
  
  
  
  if is_file_saved(doc) :  
  
      print doc.GetDocumentName() + " was saved."  
  
  else:  
  
      c4d.gui.MessageDialog("This document has not been previously saved, please save it now.")  
  
  
  
      path = c4d.storage.SaveDialog(type=c4d.FILESELECTTYPE_SCENES , title="Save", force_suffix="c4d", def_path="")  
        
  
      c4d.documents.SaveDocument(doc, path, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST,format=c4d.FORMAT_C4DEXPORT)  
  
      c4d.documents.LoadFile(path)                             
      c4d.documents.KillDocument(doc)  
        
  
if __name__=='__main__':  
  main()  
  

Best wishes
Martin

On 24/10/2014 at 14:07, xxxxxxxx wrote:

Thanks for that! Is this what Cinema 4D is doing behind the scenes? I'm wary of having two instances of a document in memory at the same time. I suppose the solution is to kill the document before loading it.

On 24/10/2014 at 17:09, xxxxxxxx wrote:

Hi Donovan,

first of all thanks for the hint with the order of loading and killing.
vice versa as a gunshot;)
 
I would be glad to know all the things Cinema 4D is doing behind the scene, but I´m pretty sure something similar is going on.

I really prefere not using call commands, too.

Best wishes
Martin

On 24/10/2014 at 18:24, xxxxxxxx wrote:

I don't understand why you'd want the user to be able to change the name of the current document if they're going to be still working on it?

This makes more sense to me.
The scene gets saved without the file browser opening. So the user is always working in the current scene:

#This code checks if the document has been changed and not saved  
#Then returns the correct file name string value depending if it was saved, or not saved  
  
import c4d  
def main() :  
    
  name = doc.GetDocumentName()  
  fn = doc.GetDocumentPath()   
  docName = ""  
    
  #Checks if the document was changed since the last save operation  
  unsaved = doc.GetChanged()  
    
  if(unsaved) :  
      #name = name[ :-4 ] #Strips out the .c4d part if desired   
      name += " *"   
      docName = name  
  
      #You can make a message pop up here if you want  
      #Or   
      #you can automatically just save the document using c4d.CallCommand(12098)  
            
  else: docName = name  
  
  print docName   
  
if __name__=='__main__':  
  main()

-ScottA

On 25/10/2014 at 01:59, xxxxxxxx wrote:

Hi Scott,

imagine a scenery where you want to set a scene management programmatically for the user.
Where you define all the render passes and rearrange  them after rendering.
Therefore the doc should be saved with a well defined name and path.
The user only have to choose where he want to place the folder structure.
That´s a way I´m using it.

Best wishes
Martin

On 30/10/2014 at 16:09, xxxxxxxx wrote:

@ScottA - @monkeytack's explanation pretty much hits the nail on the head. I want the user to be able to specify a save location in those instances where the scene hasn't already been saved (which wasn't clear from some of the code I initially posted).