/* win32 document data type Created July 1994, Mark Hammond (MHammond@skippinet.com.au) Note that this source file contains embedded documentation. This documentation consists of marked up text inside the C comments, and is prefixed with an '@' symbol. The source files are processed by a tool called "autoduck" which generates Windows .hlp files. @doc */ #include "stdafx.h" #include "win32win.h" #include "win32doc.h" #include "win32template.h" ///////////////////////////////////////////////////////////////////// // // Document object // ////////////////////////////////////////////////////////////////////// PyCDocument::PyCDocument() { } PyCDocument::~PyCDocument() { } /*static*/CDocument *PyCDocument::GetDoc(PyObject *self) { return (CDocument *)GetGoodCppObject( self, &type); } // @pymethod |PyCDocument|DoFileSave|Checks the file attributes. // If the file is read only, a new name is prompted, else the // file is saved (by calling DoSave) PyObject * ui_doc_do_file_save(PyObject *self, PyObject *args) { CHECK_NO_ARGS2(args,DoFileSave); CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; GUI_BGN_SAVE; BOOL rc = pDoc->CDocument::DoFileSave(); // @pyundocmfc CDocument|DoFileSave GUI_END_SAVE; // @xref if (rc==FALSE) RETURN_ERR("DoFileSave failed"); RETURN_NONE; } // @pymethod |PyCDocument|DeleteContents|Call the MFC DeleteContents method. // This routine is provided so a document object which overrides this method // can call the original MFC version if required. static PyObject * ui_doc_delete_contents(PyObject *self, PyObject *args) { CHECK_NO_ARGS(args); CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; // @xref GUI_BGN_SAVE; pDoc->CDocument::DeleteContents(); // @pyseemfc CDocument|DeleteContents GUI_END_SAVE; RETURN_NONE; } // @pymethod |PyCDocument|DoSave|Calls the underlying MFC DoSave method. PyObject * ui_doc_do_save(PyObject *self, PyObject *args) { // @comm If invalid or no filename, will prompt for a name, else // will perform the actual saving of the document. TCHAR *fileName; PyObject *obfileName; int bReplace = TRUE; if (!PyArg_ParseTuple(args,"O|i", &obfileName, // @pyparm string|fileName||The name of the file to save to. &bReplace)) // @pyparm int|bReplace|1|Should an existing file be silently replaced?. return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyWinObject_AsTCHAR(obfileName, &fileName, FALSE)) return NULL; // @xref GUI_BGN_SAVE; BOOL rc = pDoc->CDocument::DoSave(fileName, bReplace); // @pyundocmfc CDocument|DoSave GUI_END_SAVE; PyWinObject_FreeTCHAR(fileName); if (rc==FALSE) RETURN_ERR("DoSave failed"); RETURN_NONE; } // @pymethod |PyCDocument|GetFirstView|Returns the first view object attached to this document. PyObject * ui_doc_get_first_view(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,GetFirstView); POSITION pos = pDoc->GetFirstViewPosition(); // @pyseemfc CDocument|GetFirstViewPosition if (pos==NULL) RETURN_NONE; GUI_BGN_SAVE; CView *pWnd = pDoc->GetNextView( pos ); // @pyseemfc CDocument|GetNextView GUI_END_SAVE; // @comm For more info, see ASSERT(pWnd); // shouldnt be possible. return ui_assoc_object::make(UITypeFromCObject(pWnd), pWnd)->GetGoodRet(); } // @pymethod [,...]|PyCDocument|GetAllViews|Returns a list of all views for the current document. PyObject * ui_doc_get_all_views(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,GetAllViews); PyObject *retList = PyList_New(0); GUI_BGN_SAVE; POSITION pos = pDoc->GetFirstViewPosition(); // @pyseemfc CDocument|GetFirstViewPosition GUI_END_SAVE; while (pos!=NULL) { GUI_BGN_SAVE; CView *pWnd = pDoc->GetNextView( pos ); // @pyseemfc CDocument|GetNextView GUI_END_SAVE; ASSERT(pWnd); // shouldnt be possible. if (pWnd==NULL) { Py_DECREF(retList); RETURN_ERR("No view was available!"); } PyObject *newObj = ui_assoc_object::make(UITypeFromCObject(pWnd), pWnd)->GetGoodRet(); if (newObj==NULL) { Py_DECREF(retList); return NULL; } PyList_Append(retList, newObj); Py_DECREF(newObj); } return retList; } // @pymethod string|PyCDocument|GetPathName|Returns the full path name of the current document. // The string will be empty if no path name has been set. PyObject * ui_doc_get_path_name(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,GetPathName); GUI_BGN_SAVE; CString path = pDoc->GetPathName(); // @pyseemfc CDocument|GetPathName GUI_END_SAVE; return PyWinObject_FromTCHAR(path); } // @pymethod |PyCDocument|GetDocTemplate|Returns the template for the document. PyObject * ui_doc_get_template(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,GetDocTemplate); GUI_BGN_SAVE; CDocTemplate *ret = pDoc->GetDocTemplate(); GUI_END_SAVE; // @pyseemfc CDocument|GetDocTemplate return ui_assoc_object::make(PyCDocTemplate::type, ret)->GetGoodRet(); } // @pymethod string|PyCDocument|GetTitle|Returns the title of the current document. // This will often be the file name portion of the path name. PyObject * ui_doc_get_title(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,GetTitle); GUI_BGN_SAVE; CString path = pDoc->GetTitle(); // @pyseemfc CDocument|GetTitle GUI_END_SAVE; return PyWinObject_FromTCHAR(path); } // @pymethod int|PyCDocument|IsModified|Return a flag indicating if the document has been modified. PyObject * ui_doc_is_modified(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; CHECK_NO_ARGS2(args,IsModified); GUI_BGN_SAVE; int rc = pDoc->IsModified(); GUI_END_SAVE; return Py_BuildValue("i", rc); // @pyseemfc CDocument|IsModified } // @pymethod |PyCDocument|OnCloseDocument|Call the MFC OnCloseDocument handler. // This routine is provided so a document object which overrides this method // can call the original MFC version if required. static PyObject * ui_doc_on_close(PyObject *self, PyObject *args) { CHECK_NO_ARGS2(args,OnCloseDocument); CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; // @xref GUI_BGN_SAVE; pDoc->CDocument::OnCloseDocument(); // @pyseemfc CDocument|OnCloseDocument GUI_END_SAVE; RETURN_NONE; } // @pymethod |PyCDocument|OnNewDocument|Call the MFC OnNewDocument handler. // This routine is provided so a document object which overrides this method // can call the original MFC version if required. static PyObject * ui_doc_on_new(PyObject *self, PyObject *args) { CHECK_NO_ARGS(args); CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; // @xref GUI_BGN_SAVE; BOOL ok = pDoc->CDocument::OnNewDocument(); GUI_END_SAVE; if (!ok) // @pyseemfc CDocument|OnNewDocument RETURN_ERR("OnNewDocument failed"); RETURN_NONE; } // @pymethod |PyCDocument|OnOpenDocument|Call the MFC OnOpenDocument handler. // This routine is provided so a document object which overrides this method // can call the original MFC version if required. static PyObject * ui_doc_on_open(PyObject *self, PyObject *args) { TCHAR *pathName; PyObject *obpathName; if (!PyArg_ParseTuple(args, "O", &obpathName)) // @pyparm string|pathName||The full path of the file to open. return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyWinObject_AsTCHAR(obpathName, &pathName, FALSE)) return NULL; GUI_BGN_SAVE; BOOL ok = pDoc->OnOpenDocument(pathName); GUI_END_SAVE; PyWinObject_FreeTCHAR(pathName); if (!ok) // @pyseemfc CDocument|OnOpenDocument RETURN_ERR("OnOpenDocument failed"); RETURN_NONE; } // @pymethod |PyCDocument|OnSaveDocument|Call the MFC OnSaveDocument handler. // This routine is provided so a document object which overrides this method // can call the original MFC version if required. static PyObject * ui_doc_on_save(PyObject *self, PyObject *args) { TCHAR *pathName; PyObject *obpathName; if (!PyArg_ParseTuple(args, "O", &obpathName)) // @pyparm string|pathName||The full path of the file to save. return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyWinObject_AsTCHAR(obpathName, &pathName, FALSE)) return NULL; GUI_BGN_SAVE; BOOL ok = pDoc->OnSaveDocument(pathName); GUI_END_SAVE; PyWinObject_FreeTCHAR(pathName); if (!ok) // @pyseemfc CDocument|OnSaveDocument RETURN_ERR("OnSaveDocument failed"); RETURN_NONE; } // @pymethod int|PyCDocument|SaveModified|Call the underlying MFC method. static PyObject * ui_doc_save_modified(PyObject *self, PyObject *args) { CHECK_NO_ARGS2(args,SaveModified); CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; // @xref GUI_BGN_SAVE; BOOL rc = pDoc->CDocument::SaveModified(); // @pyseemfc CDocument|SaveModified GUI_END_SAVE; // @rdesc Nonzero if it is safe to continue and close the document; 0 if the document should not be closed. return PyInt_FromLong(rc); } // @pymethod |PyCDocument|SetModifiedFlag|Set the "dirty" flag for the document. static PyObject * ui_doc_set_modified_flag(PyObject *self, PyObject *args) { BOOL bModified = TRUE; if (!PyArg_ParseTuple(args, "|i:SetModifiedFlag", &bModified)) // @pyparm int|bModified|1|Set dirty flag return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; GUI_BGN_SAVE; pDoc->SetModifiedFlag(bModified); // @pyseemfc CDocument|SetModifiedFlag GUI_END_SAVE; RETURN_NONE; } // @pymethod |PyCDocument|SetPathName|Set the full path name for the document. PyObject * ui_doc_set_path_name(PyObject *self, PyObject *args) { TCHAR *path; PyObject *obpath; if (!PyArg_ParseTuple(args, "O:SetPathName", &obpath)) // @pyparm string|path||The full path of the file. return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyWinObject_AsTCHAR(obpath, &path, FALSE)) return NULL; GUI_BGN_SAVE; pDoc->SetPathName(path); // @pyseemfc CDocument|SetPathName GUI_END_SAVE; PyWinObject_FreeTCHAR(path); RETURN_NONE; } // @pymethod |PyCDocument|SetTitle|Set the title of the document (ie, the name // to appear in the window caption for the document. static PyObject * ui_doc_set_title(PyObject *self, PyObject *args) { TCHAR *title; PyObject *obtitle; if (!PyArg_ParseTuple(args, "O", &obtitle)) // @pyparm string|title||The new title. return NULL; if (!PyWinObject_AsTCHAR(obtitle, &title, FALSE)) return NULL; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; GUI_BGN_SAVE; pDoc->SetTitle(title); // @pyseemfc CDocument|SetTitle GUI_END_SAVE; PyWinObject_FreeTCHAR(title); RETURN_NONE; } // @pymethod |PyCDocument|UpdateAllViews|Informs each view when a document changes. static PyObject * ui_doc_update_all_views(PyObject *self, PyObject *args) { PyObject *obSender; PyObject *obHint = Py_None; CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyArg_ParseTuple(args, "O|O:UpdateAllViews", &obSender, // @pyparm |sender||The view who initiated the update &obHint)) // @pyparm object|hint|None|A hint for the update. return NULL; CView *pView = NULL; if (obSender!=Py_None) { if (!(pView=PyCView::GetViewPtr(obSender))) return NULL; } if (obHint==Py_None) obHint = NULL; GUI_BGN_SAVE; pDoc->UpdateAllViews(pView, (LPARAM)obHint);// @pyseemfc CDocument|UpdateAllViews GUI_END_SAVE; RETURN_NONE; } // @pymethod |PyCDocument|OnChangedViewList|Informs the document when a view is added or removed. static PyObject * ui_doc_on_changed_view_list(PyObject *self, PyObject *args) { CDocument *pDoc; if (!(pDoc=PyCDocument::GetDoc(self))) return NULL; if (!PyArg_ParseTuple(args, ":OnChangedViewList")) return NULL; GUI_BGN_SAVE; pDoc->CDocument::OnChangedViewList(); GUI_END_SAVE; RETURN_NONE; } /////////////////////////////////////// // // Document Methods // // inherited from assoc_object // /////////////////////////////////////// // @object PyCDocument|A document class. Encapsulates an MFC class static struct PyMethodDef ui_doc_methods[] = { {"DeleteContents", ui_doc_delete_contents, 1}, // @pymeth DeleteContents|Call the MFC DeleteContents method. {"DoSave", ui_doc_do_save, 1}, // @pymeth DoSave|Save the file. If necessary, prompt for file name. {"DoFileSave", ui_doc_do_file_save, 1}, // @pymeth DoFileSave|Check file attributes, and save the file. {"GetDocTemplate", ui_doc_get_template, 1}, // @pymeth GetDocTemplate|Returns the for the document. {"GetAllViews", ui_doc_get_all_views, 1}, // @pymeth GetAllViews|Returns a list of all views for the current document. {"GetFirstView", ui_doc_get_first_view, 1}, // @pymeth GetFirstView|Returns the first view object attached to this document. {"GetPathName", ui_doc_get_path_name, 1}, // @pymeth GetPathName|Returns the full path name of the current document. {"GetTitle", ui_doc_get_title, 1}, // @pymeth GetTitle|Returns the title of the current document. {"IsModified", ui_doc_is_modified, 1}, // @pymeth IsModified|Return a flag indicating if the document has been modified. {"OnChangedViewList", ui_doc_on_changed_view_list, 1}, // @pymeth OnChangedViewList|Informs the document when a view is added or removed. {"OnCloseDocument", ui_doc_on_close, 1}, // @pymeth OnCloseDocument|Call the MFC OnCloseDocument handler. {"OnNewDocument", ui_doc_on_new, 1}, // @pymeth OnNewDocument|Call the MFC OnNewDocument handler. {"OnOpenDocument", ui_doc_on_open, 1}, // @pymeth OnOpenDocument|Call the MFC OnOpenDocument handler. {"OnSaveDocument", ui_doc_on_save, 1}, // @pymeth OnSaveDocument|Call the MFC OnSaveDocument handler. {"SetModifiedFlag", ui_doc_set_modified_flag, 1}, // @pymeth SetModifiedFlag|Set the "dirty" flag for the document. {"SaveModified", ui_doc_save_modified, 1}, // @pymeth SaveModified|Call the underlying MFC method. {"SetPathName", ui_doc_set_path_name, 1}, // @pymeth SetPathName|Set the full path name for the document. {"SetTitle", ui_doc_set_title, 1}, // @pymeth SetTitle|Set the title of the document. {"UpdateAllViews", ui_doc_update_all_views, 1}, // @pymeth UpdateAllViews|Informs each view when a document changes. {NULL, NULL} /* sentinel */ }; ui_type_CObject PyCDocument::type("PyCDocument", &PyCCmdTarget::type, // @base PyCDocument|PyCCmdTarget RUNTIME_CLASS(CDocument), sizeof(PyCDocument), PYOBJ_OFFSET(PyCDocument), ui_doc_methods, GET_PY_CTOR(PyCDocument) );