mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-07-23 13:54:54 +02:00
[NEW_FEATURE] Automatic Backup System (in progress).
git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1203 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
parent
f12faf0ac8
commit
9c9fa8c484
@ -5797,6 +5797,27 @@ void Notepad_plus::showQuoteFromIndex(int index) const
|
|||||||
::CloseHandle(hThread);
|
::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 )
|
#pragma warning( disable : 4127 )
|
||||||
//--FLS: undoStreamComment: New function to undo stream comment around or within selection end-points.
|
//--FLS: undoStreamComment: New function to undo stream comment around or within selection end-points.
|
||||||
|
@ -305,6 +305,10 @@ public:
|
|||||||
return _accelerator.getAccTable();
|
return _accelerator.getAccTable();
|
||||||
};
|
};
|
||||||
bool emergency(generic_string emergencySavedDir);
|
bool emergency(generic_string emergencySavedDir);
|
||||||
|
Buffer * getCurrentBuffer() {
|
||||||
|
return _pEditView->getCurrentBuffer();
|
||||||
|
};
|
||||||
|
void launchDocumentBackupTask();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -640,6 +644,7 @@ private:
|
|||||||
return randomNumber;
|
return randomNumber;
|
||||||
return (rand() % rangeMax);
|
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);
|
sprintf(dest, "Loading time : %.0lf seconds", loadTime);
|
||||||
::MessageBoxA(NULL, dest, "", MB_OK);
|
::MessageBoxA(NULL, dest, "", MB_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lauch backup task
|
||||||
|
//_notepad_plus_plus_core.launchDocumentBackupTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notepad_plus_Window::isDlgsMsg(MSG *msg, bool unicodeSupported) const
|
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);
|
::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 (notification->modificationType & SC_MOD_CHANGEFOLD)
|
||||||
{
|
{
|
||||||
if (prevWasEdit)
|
if (prevWasEdit)
|
||||||
{
|
{
|
||||||
notifyView->foldChanged(notification->line,
|
notifyView->foldChanged(notification->line, notification->foldLevelNow, notification->foldLevelPrev);
|
||||||
notification->foldLevelNow, notification->foldLevelPrev);
|
|
||||||
prevWasEdit = false;
|
prevWasEdit = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +73,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
|
|||||||
{
|
{
|
||||||
prevWasEdit = false;
|
prevWasEdit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
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
|
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),
|
: _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();
|
NppParameters *pNppParamInst = NppParameters::getInstance();
|
||||||
const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings();
|
const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings();
|
||||||
@ -612,7 +613,123 @@ bool FileManager::moveFile(BufferID id, const TCHAR * newFileName)
|
|||||||
return true;
|
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);
|
Buffer * buffer = getBufferByID(id);
|
||||||
bool isHidden = false;
|
bool isHidden = false;
|
||||||
bool isSys = false;
|
bool isSys = false;
|
||||||
@ -696,7 +813,8 @@ bool FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool isCopy, g
|
|||||||
if (isSys)
|
if (isSys)
|
||||||
::SetFileAttributes(fullpath, attrib | FILE_ATTRIBUTE_SYSTEM);
|
::SetFileAttributes(fullpath, attrib | FILE_ATTRIBUTE_SYSTEM);
|
||||||
|
|
||||||
if (isCopy) {
|
if (isCopy)
|
||||||
|
{
|
||||||
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault);
|
_pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault);
|
||||||
return true; //all done
|
return true; //all done
|
||||||
}
|
}
|
||||||
|
@ -95,20 +95,15 @@ public:
|
|||||||
bool reloadBuffer(BufferID id);
|
bool reloadBuffer(BufferID id);
|
||||||
bool reloadBufferDeferred(BufferID id);
|
bool reloadBufferDeferred(BufferID id);
|
||||||
bool saveBuffer(BufferID id, const TCHAR * filename, bool isCopy = false, generic_string * error_msg = NULL);
|
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 deleteFile(BufferID id);
|
||||||
bool moveFile(BufferID id, const TCHAR * newFilename);
|
bool moveFile(BufferID id, const TCHAR * newFilename);
|
||||||
|
|
||||||
bool createEmptyFile(const TCHAR * path);
|
bool createEmptyFile(const TCHAR * path);
|
||||||
|
|
||||||
static FileManager * getInstance() {return _pSelf;};
|
static FileManager * getInstance() {return _pSelf;};
|
||||||
void destroyInstance() { delete _pSelf; };
|
void destroyInstance() { delete _pSelf; };
|
||||||
|
|
||||||
void increaseDocNr() {_nextNewNumber++;};
|
void increaseDocNr() {_nextNewNumber++;};
|
||||||
|
|
||||||
int getFileNameFromBuffer(BufferID id, TCHAR * fn2copy);
|
int getFileNameFromBuffer(BufferID id, TCHAR * fn2copy);
|
||||||
|
|
||||||
int docLength(Buffer * buffer) const;
|
int docLength(Buffer * buffer) const;
|
||||||
|
|
||||||
int getEOLFormatForm(const char *data) const;
|
int getEOLFormatForm(const char *data) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -324,6 +319,13 @@ public :
|
|||||||
generic_string getFileTime(fileTimeType ftt);
|
generic_string getFileTime(fileTimeType ftt);
|
||||||
|
|
||||||
Lang * getCurrentLang() const;
|
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 :
|
private :
|
||||||
FileManager * _pManager;
|
FileManager * _pManager;
|
||||||
bool _canNotify;
|
bool _canNotify;
|
||||||
@ -351,6 +353,7 @@ private :
|
|||||||
//Environment properties
|
//Environment properties
|
||||||
DocFileStatus _currentStatus;
|
DocFileStatus _currentStatus;
|
||||||
time_t _timeStamp; // 0 if it's a new doc
|
time_t _timeStamp; // 0 if it's a new doc
|
||||||
|
//time_t _backupModifiedTimeStamp; // 0 if backup file is not created
|
||||||
bool _isFileReadOnly;
|
bool _isFileReadOnly;
|
||||||
generic_string _fullPathName;
|
generic_string _fullPathName;
|
||||||
TCHAR * _fileName; //points to filename part in _fullPathName
|
TCHAR * _fileName; //points to filename part in _fullPathName
|
||||||
@ -359,6 +362,11 @@ private :
|
|||||||
long _recentTag;
|
long _recentTag;
|
||||||
static long _recentTagCtr;
|
static long _recentTagCtr;
|
||||||
|
|
||||||
|
// For backup system
|
||||||
|
generic_string _backupFileName; // default: ""
|
||||||
|
bool _isModified; // default: false
|
||||||
|
//bool _deleteBackupNotification; // default: false
|
||||||
|
|
||||||
void updateTimeStamp();
|
void updateTimeStamp();
|
||||||
|
|
||||||
int indexOfReference(const ScintillaEditView * identifier) const;
|
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="((/\*.*?\*)/|(//.*?$))">
|
<parser id="php_function" displayName="PHP" commentExpr="((/\*.*?\*)/|(//.*?$))">
|
||||||
<classRange
|
<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 = "\{"
|
openSymbole = "\{"
|
||||||
closeSymbole = "\}"
|
closeSymbole = "\}"
|
||||||
displayMode="node">
|
displayMode="node">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user