[NEW_FEATURE] Automatic Backup System (in progress).

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1203 f5eea248-9336-0410-98b8-ebc06183d4e3
remotes/trunk
Don Ho 11 years ago
parent f12faf0ac8
commit 9c9fa8c484

@ -5797,6 +5797,27 @@ void Notepad_plus::showQuoteFromIndex(int index) const
::CloseHandle(hThread);
}
void Notepad_plus::launchDocumentBackupTask()
{
HANDLE hThread = ::CreateThread(NULL, 0, backupDocument, this, 0, NULL);
::CloseHandle(hThread);
}
DWORD WINAPI Notepad_plus::backupDocument(void *param)
{
Notepad_plus *notepad_plus = static_cast<Notepad_plus *>(param);
//static int i = 0;
while (notepad_plus)
{
::Sleep(3000);
//printInt(i++);
// if current document is dirty, write it in the backup system
Buffer *currentBuffer = notepad_plus->getCurrentBuffer();
MainFileManager->backupBuffer((BufferID)currentBuffer, currentBuffer->getFullPathName());
}
return TRUE;
}
#pragma warning( disable : 4127 )
//--FLS: undoStreamComment: New function to undo stream comment around or within selection end-points.

@ -305,6 +305,10 @@ public:
return _accelerator.getAccTable();
};
bool emergency(generic_string emergencySavedDir);
Buffer * getCurrentBuffer() {
return _pEditView->getCurrentBuffer();
};
void launchDocumentBackupTask();
private:
@ -640,6 +644,7 @@ private:
return randomNumber;
return (rand() % rangeMax);
};
static DWORD WINAPI backupDocument(void *params);
};

@ -222,6 +222,9 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
sprintf(dest, "Loading time : %.0lf seconds", loadTime);
::MessageBoxA(NULL, dest, "", MB_OK);
}
// Lauch backup task
//_notepad_plus_plus_core.launchDocumentBackupTask();
}
bool Notepad_plus_Window::isDlgsMsg(MSG *msg, bool unicodeSupported) const

@ -55,12 +55,17 @@ BOOL Notepad_plus::notify(SCNotification *notification)
::InvalidateRect(notifyView->getHSelf(), NULL, TRUE);
}
if (notification->modificationType & (SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT | SC_PERFORMED_UNDO | SC_PERFORMED_REDO))
{
// for the backup system
_pEditView->getCurrentBuffer()->setModifiedStatus(true);
}
if (notification->modificationType & SC_MOD_CHANGEFOLD)
{
if (prevWasEdit)
{
notifyView->foldChanged(notification->line,
notification->foldLevelNow, notification->foldLevelPrev);
notifyView->foldChanged(notification->line, notification->foldLevelNow, notification->foldLevelPrev);
prevWasEdit = false;
}
}
@ -68,6 +73,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
{
prevWasEdit = false;
}
}
break;

@ -47,7 +47,8 @@ const int LF = 0x0A;
Buffer::Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus type, const TCHAR *fileName) //type must be either DOC_REGULAR or DOC_UNNAMED
: _pManager(pManager), _id(id), _isDirty(false), _doc(doc), _isFileReadOnly(false), _isUserReadOnly(false), _recentTag(-1), _references(0),
_canNotify(false), _timeStamp(0), _needReloading(false), _encoding(-1)
_canNotify(false), _timeStamp(0), _needReloading(false), _encoding(-1), _backupFileName(TEXT("")), _isModified(false)
//, _deleteBackupNotification(false), _backupModifiedTimeStamp(0)
{
NppParameters *pNppParamInst = NppParameters::getInstance();
const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings();
@ -612,7 +613,123 @@ bool FileManager::moveFile(BufferID id, const TCHAR * newFileName)
return true;
}
bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, generic_string * error_msg) {
bool FileManager::backupBuffer(BufferID id, const TCHAR * filename)
{
Buffer * buffer = getBufferByID(id);
TCHAR fullpath[MAX_PATH];
::GetFullPathName(filename, MAX_PATH, fullpath, NULL);
::GetLongPathName(fullpath, fullpath, MAX_PATH);
/*
time_t currentBakModifTimestamp = buffer->getBackupModifiedTimeStamp();
time_t lastBakModifTimestamp = 0;
if (PathFileExists(fullpath))
{
struct _stat statBuf;
if (!generic_stat(fullpath, &statBuf))
{
if (currentBakModifTimestamp == statBuf.st_mtime)
return true;
lastBakModifTimestamp = statBuf.st_mtime;
}
}
*/
if (buffer->isDirty())
{
if (buffer->isModified()) // buffer dirty and modified, write the backup file
{
UniMode mode = buffer->getUnicodeMode();
if (mode == uniCookie)
mode = uni8Bit; //set the mode to ANSI to prevent converter from adding BOM and performing conversions, Scintilla's data can be copied directly
Utf8_16_Write UnicodeConvertor;
UnicodeConvertor.setEncoding(mode);
int encoding = buffer->getEncoding();
FILE *fp = UnicodeConvertor.fopen(fullpath, TEXT("wb"));
if (fp)
{
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, buffer->_doc); //generate new document
int lengthDoc = _pscratchTilla->getCurrentDocLen();
char* buf = (char*)_pscratchTilla->execute(SCI_GETCHARACTERPOINTER); //to get characters directly from Scintilla buffer
size_t items_written = 0;
if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write
{
items_written = UnicodeConvertor.fwrite(buf, lengthDoc);
if (lengthDoc == 0)
items_written = 1;
}
else
{
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
int grabSize;
for (int i = 0; i < lengthDoc; i += grabSize)
{
grabSize = lengthDoc - i;
if (grabSize > blockSize)
grabSize = blockSize;
int newDataLen = 0;
int incompleteMultibyteChar = 0;
const char *newData = wmc->encode(SC_CP_UTF8, encoding, buf+i, grabSize, &newDataLen, &incompleteMultibyteChar);
grabSize -= incompleteMultibyteChar;
items_written = UnicodeConvertor.fwrite(newData, newDataLen);
}
if (lengthDoc == 0)
items_written = 1;
}
UnicodeConvertor.fclose();
// Error, we didn't write the entire document to disk.
// Note that fwrite() doesn't return the number of bytes written, but rather the number of ITEMS.
if(items_written != 1)
{
return false;
}
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault);
/*
if (lastBakModifTimestamp != 0)
buffer->setBackupModifiedTimeStamp(lastBakModifTimestamp);
else
{
struct _stat statBuf;
if (!generic_stat(fullpath, &statBuf))
{
buffer->setBackupModifiedTimeStamp(statBuf.st_mtime);
}
}
*/
buffer->setModifiedStatus(false);
return true; //all done
}
return false; // fopen failed
}
return true; // buffer dirty nut unmodified
}
else // buffer not dirty, sync: delete the backup file
{
generic_string backupFilePath = buffer->getBackupFileName();
if (backupFilePath != TEXT(""))
{
// delete backup file
return true; // backup file deleted
}
return true; // no backup file to delete
}
}
bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, generic_string * error_msg)
{
Buffer * buffer = getBufferByID(id);
bool isHidden = false;
bool isSys = false;
@ -696,7 +813,8 @@ bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, g
if (isSys)
::SetFileAttributes(fullpath, attrib | FILE_ATTRIBUTE_SYSTEM);
if (isCopy) {
if (isCopy)
{
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault);
return true; //all done
}

@ -95,20 +95,15 @@ public:
bool reloadBuffer(BufferID id);
bool reloadBufferDeferred(BufferID id);
bool saveBuffer(BufferID id, const TCHAR * filename, bool isCopy = false, generic_string * error_msg = NULL);
bool backupBuffer(BufferID id, const TCHAR * filename);
bool deleteFile(BufferID id);
bool moveFile(BufferID id, const TCHAR * newFilename);
bool createEmptyFile(const TCHAR * path);
static FileManager * getInstance() {return _pSelf;};
void destroyInstance() { delete _pSelf; };
void increaseDocNr() {_nextNewNumber++;};
int getFileNameFromBuffer(BufferID id, TCHAR * fn2copy);
int docLength(Buffer * buffer) const;
int getEOLFormatForm(const char *data) const;
private:
@ -324,6 +319,13 @@ public :
generic_string getFileTime(fileTimeType ftt);
Lang * getCurrentLang() const;
//time_t getBackupModifiedTimeStamp() const {return _backupModifiedTimeStamp;};
//void setBackupModifiedTimeStamp(time_t timestamp2Set) {_backupModifiedTimeStamp = timestamp2Set;};
bool isModified() const {return _isModified;};
void setModifiedStatus(bool isModified) {_isModified = isModified;};
generic_string getBackupFileName() const {return _backupFileName;};
private :
FileManager * _pManager;
bool _canNotify;
@ -351,6 +353,7 @@ private :
//Environment properties
DocFileStatus _currentStatus;
time_t _timeStamp; // 0 if it's a new doc
//time_t _backupModifiedTimeStamp; // 0 if backup file is not created
bool _isFileReadOnly;
generic_string _fullPathName;
TCHAR * _fileName; //points to filename part in _fullPathName
@ -359,6 +362,11 @@ private :
long _recentTag;
static long _recentTagCtr;
// For backup system
generic_string _backupFileName; // default: ""
bool _isModified; // default: false
//bool _deleteBackupNotification; // default: false
void updateTimeStamp();
int indexOfReference(const ScintillaEditView * identifier) const;

@ -171,7 +171,7 @@ http://notepad-plus-plus.org/features/function-list.html
<parser id="php_function" displayName="PHP" commentExpr="((/\*.*?\*)/|(//.*?$))">
<classRange
mainExpr="^[\s]*(class|abstract[\s]+class|final[\s]+class)[\t ]+[\w]+([\s]*|[\s]*(extends|implements)[\s]+[\w]+[\s]*)?\{"
mainExpr="^[\s]*(class|abstract[\s]+class|final[\s]+class)[\t ]+[\w]+([\s]*|[\s]*(extends|implements)[\s]+[\w\\]+[\s]*)?\{"
openSymbole = "\{"
closeSymbole = "\}"
displayMode="node">

Loading…
Cancel
Save