+ Make transient directory of the form ExeName_Doc_{UUID}_{HASH}_{PID}

+ Set some properties in Document read-only

+ Implement Document::saveAs

+ Fix PropertyUUID::setValue()

+ Add a field for UUID in document information panel
This commit is contained in:
wmayer 2013-05-04 03:16:34 +02:00
parent 9ad4bb5595
commit 2bbe465229
9 changed files with 216 additions and 112 deletions

View File

@ -421,6 +421,23 @@ Document* Application::openDocument(const char * FileName)
// read the document
newDoc->restore();
// make sure that the uuid is unique
//FIXME: See Document::saveAs()
#if 0
std::string uuid = newDoc->Uid.getValueStr();
for (std::map<std::string,Document*>::iterator it = DocMap.begin(); it != DocMap.end(); ++it) {
if (newDoc != it->second) {
if (uuid == it->second->Uid.getValueStr()) {
Base::Uuid id;
newDoc->Uid.setValue(id);
Base::Console().Warning("Document with the UUID '%s' already exists, change to '%s'\n",
uuid.c_str(), id.getValue().c_str());
break;
}
}
}
#endif
return newDoc;
}

View File

@ -65,6 +65,9 @@ recompute path. Also enables more complicated dependencies beyond trees.
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <QCoreApplication>
#include <QCryptographicHash>
#include "Document.h"
#include "DocumentPy.h"
@ -525,7 +528,7 @@ Document::Document(void)
#endif
ADD_PROPERTY_TYPE(Label,("Unnamed"),0,Prop_None,"The name of the document");
ADD_PROPERTY_TYPE(FileName,(""),0,Prop_None,"The path to the file where the document is saved to");
ADD_PROPERTY_TYPE(FileName,(""),0,Prop_ReadOnly,"The path to the file where the document is saved to");
ADD_PROPERTY_TYPE(CreatedBy,(""),0,Prop_None,"The creator of the document");
ADD_PROPERTY_TYPE(CreationDate,(Base::TimeInfo::currentDateTimeString()),0,Prop_ReadOnly,"Date of creation");
ADD_PROPERTY_TYPE(LastModifiedBy,(""),0,Prop_None,0);
@ -537,18 +540,17 @@ Document::Document(void)
// create the uuid for the document
Base::Uuid id;
ADD_PROPERTY_TYPE(Id,(""),0,Prop_None,"ID of the document");
ADD_PROPERTY_TYPE(Uid,(id),0,Prop_None,"UUID of the document");
ADD_PROPERTY_TYPE(Uid,(id),0,Prop_ReadOnly,"UUID of the document");
// license stuff
ADD_PROPERTY_TYPE(License,("CC-BY 3.0"),0,Prop_None,"License string of the Item");
ADD_PROPERTY_TYPE(LicenseURL,("http://creativecommons.org/licenses/by/3.0/"),0,Prop_None,"URL to the license text/contract");
// create transient directory
std::string basePath = Base::FileInfo::getTempPath() + GetApplication().getExecutableName();
Base::FileInfo TransDir(basePath + "_Doc_" + id.getValue());
Base::FileInfo TransDir(getTransientDirectoryName(id.getValue(),FileName.getStrValue()));
if (!TransDir.exists())
TransDir.createDirectory();
ADD_PROPERTY_TYPE(TransientDir,(TransDir.filePath().c_str()),0,Prop_Transient,
ADD_PROPERTY_TYPE(TransientDir,(TransDir.filePath().c_str()),0,PropertyType(Prop_Transient|Prop_ReadOnly),
"Transient directory, where the files live while the document is open");
}
@ -586,6 +588,19 @@ Document::~Document()
delete d;
}
std::string Document::getTransientDirectoryName(const std::string& uuid, const std::string& filename) const
{
// Create a directory name of the form: {ExeName}_Doc_{UUID}_{HASH}_{PID}
std::stringstream s;
QCryptographicHash hash(QCryptographicHash::Sha1);
hash.addData(filename.c_str(), filename.size());
s << Base::FileInfo::getTempPath() << GetApplication().getExecutableName()
<< "_Doc_" << uuid
<< "_" << hash.result().toHex().left(6).constData()
<< "_" << QCoreApplication::applicationPid();
return s.str();
}
//--------------------------------------------------------------------------
// Exported functions
//--------------------------------------------------------------------------
@ -637,9 +652,8 @@ void Document::Restore(Base::XMLReader &reader)
Label.setValue(DocLabel.c_str());
// create new transient directory
std::string basePath = Base::FileInfo::getTempPath() + GetApplication().getExecutableName();
Base::FileInfo TransDirNew(basePath + "_Doc_" + Uid.getValueStr());
if(!TransDirNew.exists())
Base::FileInfo TransDirNew(getTransientDirectoryName(Uid.getValueStr(),FileName.getStrValue()));
if (!TransDirNew.exists())
TransDirNew.createDirectory();
TransientDir.setValue(TransDirNew.filePath());
@ -857,6 +871,34 @@ void Document::exportGraphviz(std::ostream& out)
boost::write_graphviz(out, DepList, boost::make_label_writer(&(names[0])));
}
bool Document::saveAs(const char* file)
{
Base::FileInfo fi(file);
if (this->FileName.getStrValue() != file) {
this->FileName.setValue(file);
this->Label.setValue(fi.fileNamePure());
//FIXME: At the moment PropertyFileIncluded doesn't work when renaming this directory.
// PropertyFileIncluded shouldn't store the transient path
//FIXME: Application::openDocument() may assign a new UUID. In order to change the directoy
// name handle this in onChanged()
#if 0
Base::Uuid id;
Base::FileInfo TransDirNew(getTransientDirectoryName(id.getValue(),this->FileName.getStrValue()));
Base::FileInfo TransDirOld(this->TransientDir.getStrValue());
// this directory should not exist
if (!TransDirNew.exists()) {
if (TransDirOld.renameFile(TransDirNew.filePath().c_str())) {
this->Uid.setValue(id);
this->TransientDir.setValue(TransDirNew.filePath());
}
}
#endif
}
return save();
}
// Save the document under the name it has been opened
bool Document::save (void)
{

View File

@ -133,6 +133,7 @@ public:
//void saveAs (const char* Name);
/// Save the document to the file in Property Path
bool save (void);
bool saveAs(const char* file);
/// Restore the document from the file in Property Path
void restore (void);
void exportObjects(const std::vector<App::DocumentObject*>&, std::ostream&);
@ -303,6 +304,7 @@ protected:
void _clearRedos();
/// refresh the internal dependency graph
void _rebuildDependencyList(void);
std::string getTransientDirectoryName(const std::string& uuid, const std::string& filename) const;
private:

View File

@ -15,12 +15,17 @@
</Documentation>
<Methode Name="save">
<Documentation>
<UserDocu>Save the document to disc</UserDocu>
<UserDocu>Save the document to disk</UserDocu>
</Documentation>
</Methode>
<Methode Name="saveAs">
<Documentation>
<UserDocu>Save the document under a new name to disk</UserDocu>
</Documentation>
</Methode>
<Methode Name="restore">
<Documentation>
<UserDocu>Restore the document from disc</UserDocu>
<UserDocu>Restore the document from disk</UserDocu>
</Documentation>
</Methode>
<Methode Name="exportGraphviz">

View File

@ -69,6 +69,25 @@ PyObject* DocumentPy::save(PyObject * args)
Py_Return;
}
PyObject* DocumentPy::saveAs(PyObject * args)
{
char* fn;
if (!PyArg_ParseTuple(args, "s", &fn)) // convert args: Python->C
return NULL; // NULL triggers exception
if (!getDocumentPtr()->saveAs(fn)) {
PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set");
return NULL;
}
Base::FileInfo fi(fn);
if (!fi.isReadable()) {
PyErr_Format(PyExc_IOError, "No such file or directory: '%s'", fn);
return NULL;
}
Py_Return;
}
PyObject* DocumentPy::restore(PyObject * args)
{
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C

View File

@ -1348,8 +1348,15 @@ void PropertyUUID::setPyObject(PyObject *value)
throw Py::TypeError(error);
}
// assign the string
setValue(string);
try {
// assign the string
Base::Uuid uid;
uid.setValue(string);
setValue(uid);
}
catch (const std::exception& e) {
throw Py::RuntimeError(e.what());
}
}
void PropertyUUID::Save (Base::Writer &writer) const

View File

@ -40,9 +40,6 @@
<property name="spacing" >
<number>6</number>
</property>
<item rowspan="2" row="7" column="1" >
<widget class="QTextEdit" name="textEditComment" />
</item>
<item row="0" column="0" >
<widget class="QLabel" name="textLabelName" >
<property name="text" >
@ -56,32 +53,16 @@
</property>
</widget>
</item>
<item row="8" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<item row="0" column="1" >
<widget class="QLineEdit" name="lineEditName" >
<property name="minimumSize" >
<size>
<width>91</width>
<height>240</height>
<width>0</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0" >
<widget class="QLabel" name="textLabelComment" >
<property name="text" >
<string>Commen&amp;t:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>textEditComment</cstring>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
@ -108,40 +89,30 @@
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="lineEditCreator" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="lineEditLastMod" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLabel" name="textLabelLastMod" >
<item row="2" column="0" >
<widget class="QLabel" name="textLabelUuid" >
<property name="text" >
<string>&amp;Last modified by:</string>
<string>UUID:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditLastMod</cstring>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="lineEditUuid" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" >
<item row="3" column="0" >
<widget class="QLabel" name="textLabelCreator" >
<property name="text" >
<string>Created &amp;by:</string>
@ -154,20 +125,66 @@
</property>
</widget>
</item>
<item row="6" column="0" >
<widget class="QLabel" name="textLabelCompany" >
<item row="3" column="1" >
<widget class="QLineEdit" name="lineEditCreator" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLabel" name="textLabelCreateDate" >
<property name="text" >
<string>Com&amp;pany:</string>
<string>Creation &amp;date:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditCompany</cstring>
<cstring>lineEditDate</cstring>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="lineEditDate" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QLabel" name="textLabelLastMod" >
<property name="text" >
<string>&amp;Last modified by:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditLastMod</cstring>
</property>
</widget>
</item>
<item row="5" column="1" >
<widget class="QLineEdit" name="lineEditLastMod" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="6" column="0" >
<widget class="QLabel" name="textLabelLastModDate" >
<property name="text" >
<string>Last &amp;modification date:</string>
@ -181,29 +198,6 @@
</widget>
</item>
<item row="6" column="1" >
<widget class="QLineEdit" name="lineEditCompany" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="lineEditDate" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1" >
<widget class="QLineEdit" name="lineEditLastModDate" >
<property name="minimumSize" >
<size>
@ -216,32 +210,61 @@
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="textLabelCreateDate" >
<item row="7" column="0" >
<widget class="QLabel" name="textLabelCompany" >
<property name="text" >
<string>Creation &amp;date:</string>
<string>Com&amp;pany:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>lineEditDate</cstring>
<cstring>lineEditCompany</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="lineEditName" >
<item row="7" column="1" >
<widget class="QLineEdit" name="lineEditCompany" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="readOnly" >
<bool>true</bool>
</widget>
</item>
<item row="8" column="0" >
<widget class="QLabel" name="textLabelComment" >
<property name="text" >
<string>Commen&amp;t:</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>textEditComment</cstring>
</property>
</widget>
</item>
<item rowspan="2" row="8" column="1" >
<widget class="QTextEdit" name="textEditComment" />
</item>
<item row="9" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>91</width>
<height>240</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -304,14 +327,6 @@
</widget>
<layoutdefault spacing="6" margin="11" />
<tabstops>
<tabstop>lineEditName</tabstop>
<tabstop>lineEditCreator</tabstop>
<tabstop>lineEditDate</tabstop>
<tabstop>lineEditLastMod</tabstop>
<tabstop>lineEditLastModDate</tabstop>
<tabstop>lineEditCompany</tabstop>
<tabstop>buttonOk</tabstop>
<tabstop>buttonCancel</tabstop>
</tabstops>
<resources/>
<connections>

View File

@ -46,6 +46,7 @@ DlgProjectInformationImp::DlgProjectInformationImp( App::Document* doc, QWidget*
this->setupUi(this);
lineEditName->setText(QString::fromUtf8(doc->Label.getValue()));
lineEditPath->setText(QString::fromUtf8(doc->FileName.getValue()));
lineEditUuid->setText(QString::fromUtf8(doc->Uid.getValueStr().c_str()));
lineEditCreator->setText(QString::fromUtf8(doc->CreatedBy.getValue()));
lineEditDate->setText(QString::fromUtf8(doc->CreationDate.getValue()));
lineEditLastMod->setText(QString::fromUtf8(doc->LastModifiedBy.getValue()));

View File

@ -602,12 +602,8 @@ bool Document::saveAs(void)
// save as new file name
Gui::WaitCursor wc;
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").FileName = \"%s\""
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").saveAs('%s')"
, DocName, (const char*)fn.toUtf8());
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").Label = \"%s\""
, DocName, (const char*)bn.toUtf8());
Command::doCommand(Command::Doc,"App.getDocument(\"%s\").save()"
, DocName);
setModified(false);
getMainWindow()->appendRecentFile(fi.filePath());