[NEW_FEATURE] Automatic Backup System (in progress).
git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1216 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
parent
b72f302138
commit
5512a9221c
@ -2934,7 +2934,8 @@ bool Notepad_plus::canHideView(int whichOne)
|
||||
return canHide;
|
||||
}
|
||||
|
||||
void Notepad_plus::loadBufferIntoView(BufferID id, int whichOne, bool dontClose) {
|
||||
void Notepad_plus::loadBufferIntoView(BufferID id, int whichOne, bool dontClose)
|
||||
{
|
||||
DocTabView * tabToOpen = (whichOne == MAIN_VIEW)?&_mainDocTab:&_subDocTab;
|
||||
ScintillaEditView * viewToOpen = (whichOne == MAIN_VIEW)?&_mainEditView:&_subEditView;
|
||||
|
||||
@ -2945,23 +2946,29 @@ void Notepad_plus::loadBufferIntoView(BufferID id, int whichOne, bool dontClose)
|
||||
|
||||
BufferID idToClose = BUFFER_INVALID;
|
||||
//Check if the tab has a single clean buffer. Close it if so
|
||||
if (!dontClose && tabToOpen->nbItem() == 1) {
|
||||
if (!dontClose && tabToOpen->nbItem() == 1)
|
||||
{
|
||||
idToClose = tabToOpen->getBufferByIndex(0);
|
||||
Buffer * buf = MainFileManager->getBufferByID(idToClose);
|
||||
if (buf->isDirty() || !buf->isUntitled()) {
|
||||
if (buf->isDirty() || !buf->isUntitled())
|
||||
{
|
||||
idToClose = BUFFER_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
MainFileManager->addBufferReference(id, viewToOpen);
|
||||
|
||||
if (idToClose != BUFFER_INVALID) { //close clean doc. Use special logic to prevent flicker of tab showing then hiding
|
||||
//close clean doc. Use special logic to prevent flicker of tab showing then hiding
|
||||
if (idToClose != BUFFER_INVALID)
|
||||
{
|
||||
tabToOpen->setBuffer(0, id); //index 0 since only one open
|
||||
activateBuffer(id, whichOne); //activate. DocTab already activated but not a problem
|
||||
MainFileManager->closeBuffer(idToClose, viewToOpen); //delete the buffer
|
||||
if (_pFileSwitcherPanel)
|
||||
_pFileSwitcherPanel->closeItem((int)idToClose, whichOne);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
tabToOpen->addBuffer(id);
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ public:
|
||||
|
||||
// fileOperations
|
||||
//The doXXX functions apply to a single buffer and dont need to worry about views, with the excpetion of doClose, since closing one view doesnt have to mean the document is gone
|
||||
BufferID doOpen(const TCHAR *fileName, bool isRecursive = false, bool isReadOnly = false, int encoding = -1);
|
||||
BufferID doOpen(const TCHAR *fileName, bool isRecursive = false, bool isReadOnly = false, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0);
|
||||
bool doReload(BufferID id, bool alert = true);
|
||||
bool doSave(BufferID, const TCHAR * filename, bool isSaveCopy = false);
|
||||
void doClose(BufferID, int whichOne, bool doDeleteBackup = false);
|
||||
|
@ -1398,6 +1398,8 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
|
||||
if (_pTrayIco)
|
||||
_pTrayIco->doTrayIcon(REMOVE);
|
||||
|
||||
MainFileManager->backupCurrentBuffer();
|
||||
|
||||
const NppGUI & nppgui = pNppParam->getNppGUI();
|
||||
Session currentSession;
|
||||
if (nppgui._rememberLastSession)
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <TCHAR.h>
|
||||
|
||||
|
||||
BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isRecursive, bool isReadOnly, int encoding)
|
||||
BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp)
|
||||
{
|
||||
NppParameters *pNppParam = NppParameters::getInstance();
|
||||
TCHAR longFileName[MAX_PATH];
|
||||
@ -43,6 +43,13 @@ BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isRecursive, bool isRe
|
||||
::GetFullPathName(fileName, MAX_PATH, longFileName, NULL);
|
||||
::GetLongPathName(longFileName, longFileName, MAX_PATH);
|
||||
|
||||
bool isBackupMode = backupFileName != NULL && PathFileExists(backupFileName);
|
||||
if (isBackupMode && !PathFileExists(longFileName)) // UNTITLED
|
||||
{
|
||||
lstrcpy(longFileName, fileName);
|
||||
}
|
||||
|
||||
|
||||
_lastRecentFileList.remove(longFileName);
|
||||
|
||||
const TCHAR * fileName2Find;
|
||||
@ -90,41 +97,45 @@ BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isRecursive, bool isRe
|
||||
}
|
||||
|
||||
bool globbing = wcsrchr(longFileName, TCHAR('*')) || wcsrchr(longFileName, TCHAR('?'));
|
||||
if (!PathFileExists(longFileName) && !globbing)
|
||||
{
|
||||
TCHAR str2display[MAX_PATH*2];
|
||||
generic_string longFileDir(longFileName);
|
||||
PathRemoveFileSpec(longFileDir);
|
||||
|
||||
bool isCreateFileSuccessful = false;
|
||||
if (PathFileExists(longFileDir.c_str()))
|
||||
{
|
||||
wsprintf(str2display, TEXT("%s doesn't exist. Create it?"), longFileName);
|
||||
if (::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_YESNO) == IDYES)
|
||||
{
|
||||
bool res = MainFileManager->createEmptyFile(longFileName);
|
||||
if (res)
|
||||
{
|
||||
isCreateFileSuccessful = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(str2display, TEXT("Cannot create the file \"%s\""), longFileName);
|
||||
::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isBackupMode) // if not backup mode, or backupfile path is invalid
|
||||
{
|
||||
if (!PathFileExists(longFileName) && !globbing)
|
||||
{
|
||||
TCHAR str2display[MAX_PATH*2];
|
||||
generic_string longFileDir(longFileName);
|
||||
PathRemoveFileSpec(longFileDir);
|
||||
|
||||
if (!isCreateFileSuccessful)
|
||||
{
|
||||
if (isWow64Off)
|
||||
{
|
||||
pNppParam->safeWow64EnableWow64FsRedirection(TRUE);
|
||||
isWow64Off = false;
|
||||
}
|
||||
return BUFFER_INVALID;
|
||||
}
|
||||
}
|
||||
bool isCreateFileSuccessful = false;
|
||||
if (PathFileExists(longFileDir.c_str()))
|
||||
{
|
||||
wsprintf(str2display, TEXT("%s doesn't exist. Create it?"), longFileName);
|
||||
if (::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_YESNO) == IDYES)
|
||||
{
|
||||
bool res = MainFileManager->createEmptyFile(longFileName);
|
||||
if (res)
|
||||
{
|
||||
isCreateFileSuccessful = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(str2display, TEXT("Cannot create the file \"%s\""), longFileName);
|
||||
::MessageBox(_pPublicInterface->getHSelf(), str2display, TEXT("Create new file"), MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCreateFileSuccessful)
|
||||
{
|
||||
if (isWow64Off)
|
||||
{
|
||||
pNppParam->safeWow64EnableWow64FsRedirection(TRUE);
|
||||
isWow64Off = false;
|
||||
}
|
||||
return BUFFER_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify plugins that current file is about to load
|
||||
// Plugins can should use this notification to filter SCN_MODIFIED
|
||||
@ -139,7 +150,15 @@ BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isRecursive, bool isRe
|
||||
encoding = getHtmlXmlEncoding(longFileName);
|
||||
}
|
||||
|
||||
BufferID buffer = MainFileManager->loadFile(longFileName, NULL, encoding);
|
||||
BufferID buffer;
|
||||
if (isBackupMode)
|
||||
{
|
||||
buffer = MainFileManager->loadFile(longFileName, NULL, encoding, backupFileName, fileNameTimestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = MainFileManager->loadFile(longFileName, NULL, encoding);
|
||||
}
|
||||
|
||||
if (buffer != BUFFER_INVALID)
|
||||
{
|
||||
@ -1321,16 +1340,7 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
|
||||
for ( ; i < session.nbMainFiles() ; )
|
||||
{
|
||||
// _fileName
|
||||
// _backupFilePath
|
||||
// _originalFileLastModifTimestamp
|
||||
// if _backupFilePath is not absent, then load _backupFilePath
|
||||
// otherwise load _fileName
|
||||
const TCHAR *pFn;
|
||||
if (isBackupMode && session._mainViewFiles[i]._backupFilePath != TEXT(""))
|
||||
pFn = session._mainViewFiles[i]._backupFilePath.c_str();
|
||||
else
|
||||
pFn = session._mainViewFiles[i]._fileName.c_str();
|
||||
const TCHAR *pFn = session._mainViewFiles[i]._fileName.c_str();
|
||||
|
||||
if (isFileSession(pFn))
|
||||
{
|
||||
@ -1347,7 +1357,14 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
}
|
||||
if (PathFileExists(pFn))
|
||||
{
|
||||
lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding);
|
||||
if (isBackupMode && session._mainViewFiles[i]._backupFilePath != TEXT(""))
|
||||
lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding, session._mainViewFiles[i]._backupFilePath.c_str(), session._mainViewFiles[i]._originalFileLastModifTimestamp);
|
||||
else
|
||||
lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding);
|
||||
}
|
||||
else if (isBackupMode && PathFileExists(session._mainViewFiles[i]._backupFilePath.c_str()))
|
||||
{
|
||||
lastOpened = doOpen(pFn, false, false, session._mainViewFiles[i]._encoding, session._mainViewFiles[i]._backupFilePath.c_str(), session._mainViewFiles[i]._originalFileLastModifTimestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1387,8 +1404,11 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
if (session._mainViewFiles[i]._encoding != -1)
|
||||
buf->setEncoding(session._mainViewFiles[i]._encoding);
|
||||
|
||||
if (isBackupMode && session._mainViewFiles[i]._backupFilePath != TEXT(""))
|
||||
buf->setDirty(true);
|
||||
|
||||
//Force in the document so we can add the markers
|
||||
//Dont use default methods because of performance
|
||||
//Don't use default methods because of performance
|
||||
Document prevDoc = _mainEditView.execute(SCI_GETDOCPOINTER);
|
||||
_mainEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
|
||||
for (size_t j = 0, len = session._mainViewFiles[i]._marks.size(); j < len ; ++j)
|
||||
@ -1415,11 +1435,7 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
|
||||
for ( ; k < session.nbSubFiles() ; )
|
||||
{
|
||||
const TCHAR *pFn;
|
||||
if (isBackupMode && session._subViewFiles[i]._backupFilePath != TEXT(""))
|
||||
pFn = session._subViewFiles[i]._backupFilePath.c_str();
|
||||
else
|
||||
pFn = session._subViewFiles[i]._fileName.c_str();
|
||||
const TCHAR *pFn = session._subViewFiles[i]._fileName.c_str();
|
||||
|
||||
if (isFileSession(pFn)) {
|
||||
vector<sessionFileInfo>::iterator posIt = session._subViewFiles.begin() + k;
|
||||
@ -1435,13 +1451,20 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
}
|
||||
if (PathFileExists(pFn))
|
||||
{
|
||||
lastOpened = doOpen(pFn, false, false, session._subViewFiles[k]._encoding);
|
||||
if (isBackupMode && session._subViewFiles[i]._backupFilePath != TEXT(""))
|
||||
lastOpened = doOpen(pFn, false, false, session._subViewFiles[i]._encoding, session._subViewFiles[i]._backupFilePath.c_str(), session._subViewFiles[i]._originalFileLastModifTimestamp);
|
||||
else
|
||||
lastOpened = doOpen(pFn, false, false, session._subViewFiles[i]._encoding);
|
||||
|
||||
//check if already open in main. If so, clone
|
||||
if (_mainDocTab.getIndexByBuffer(lastOpened) != -1) {
|
||||
loadBufferIntoView(lastOpened, SUB_VIEW);
|
||||
}
|
||||
}
|
||||
else if (isBackupMode && PathFileExists(session._subViewFiles[i]._backupFilePath.c_str()))
|
||||
{
|
||||
lastOpened = doOpen(pFn, false, false, session._subViewFiles[i]._encoding, session._subViewFiles[i]._backupFilePath.c_str(), session._subViewFiles[i]._originalFileLastModifTimestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastOpened = BUFFER_INVALID;
|
||||
@ -1487,9 +1510,12 @@ bool Notepad_plus::loadSession(Session & session, bool isBackupMode)
|
||||
}
|
||||
buf->setLangType(typeToSet, pLn);
|
||||
buf->setEncoding(session._subViewFiles[k]._encoding);
|
||||
|
||||
if (isBackupMode && session._mainViewFiles[i]._backupFilePath != TEXT(""))
|
||||
buf->setDirty(true);
|
||||
|
||||
//Force in the document so we can add the markers
|
||||
//Dont use default methods because of performance
|
||||
//Don't use default methods because of performance
|
||||
Document prevDoc = _subEditView.execute(SCI_GETDOCPOINTER);
|
||||
_subEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
|
||||
for (size_t j = 0, len = session._subViewFiles[k]._marks.size(); j < len ; ++j)
|
||||
|
@ -48,7 +48,6 @@ 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), _backupFileName(TEXT("")), _isModified(false)
|
||||
//, _deleteBackupNotification(false), _backupModifiedTimeStamp(0)
|
||||
{
|
||||
NppParameters *pNppParamInst = NppParameters::getInstance();
|
||||
const NewDocDefaultSettings & ndds = (pNppParamInst->getNppGUI()).getNewDocDefaultSettings();
|
||||
@ -457,7 +456,8 @@ void FileManager::closeBuffer(BufferID id, ScintillaEditView * identifier) {
|
||||
}
|
||||
}
|
||||
|
||||
BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encoding)
|
||||
// backupFileName is sentinel of backup mode: if it's not NULL, then we use it (load it). Otherwise we use filename
|
||||
BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encoding, const TCHAR *backupFileName, time_t fileNameTimestamp)
|
||||
{
|
||||
bool ownDoc = false;
|
||||
if (doc == NULL)
|
||||
@ -469,15 +469,30 @@ BufferID FileManager::loadFile(const TCHAR * filename, Document doc, int encodin
|
||||
TCHAR fullpath[MAX_PATH];
|
||||
::GetFullPathName(filename, MAX_PATH, fullpath, NULL);
|
||||
::GetLongPathName(fullpath, fullpath, MAX_PATH);
|
||||
|
||||
bool isBackupMode = backupFileName != NULL && PathFileExists(backupFileName);
|
||||
if (isBackupMode && !PathFileExists(fullpath)) // if backup mode and fullpath doesn't exist, we guess is UNTITLED
|
||||
{
|
||||
lstrcpy(fullpath, filename); // we restore fullpath with filename, in our case is "new #"
|
||||
}
|
||||
|
||||
Utf8_16_Read UnicodeConvertor; //declare here so we can get information after loading is done
|
||||
|
||||
formatType format;
|
||||
bool res = loadFileData(doc, fullpath, &UnicodeConvertor, L_TEXT, encoding, &format);
|
||||
bool res = loadFileData(doc, backupFileName?backupFileName:fullpath, &UnicodeConvertor, L_TEXT, encoding, &format);
|
||||
if (res)
|
||||
{
|
||||
Buffer * newBuf = new Buffer(this, _nextBufferID, doc, DOC_REGULAR, fullpath);
|
||||
BufferID id = (BufferID) newBuf;
|
||||
newBuf->_id = id;
|
||||
if (backupFileName != NULL)
|
||||
{
|
||||
newBuf->_backupFileName = backupFileName;
|
||||
if (!PathFileExists(fullpath))
|
||||
newBuf->_currentStatus = DOC_UNNAMED;
|
||||
}
|
||||
if (fileNameTimestamp != 0)
|
||||
newBuf->_timeStamp = fileNameTimestamp;
|
||||
_buffers.push_back(newBuf);
|
||||
++_nrBufs;
|
||||
Buffer * buf = _buffers.at(_nrBufs - 1);
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
|
||||
void addBufferReference(BufferID id, ScintillaEditView * identifer); //called by Scintilla etc indirectly
|
||||
|
||||
BufferID loadFile(const TCHAR * filename, Document doc = NULL, int encoding = -1); //ID == BUFFER_INVALID on failure. If Doc == NULL, a new file is created, otherwise data is loaded in given document
|
||||
BufferID loadFile(const TCHAR * filename, Document doc = NULL, int encoding = -1, const TCHAR *backupFileName = NULL, time_t fileNameTimestamp = 0); //ID == BUFFER_INVALID on failure. If Doc == NULL, a new file is created, otherwise data is loaded in given document
|
||||
BufferID newEmptyDocument();
|
||||
//create Buffer from existing Scintilla, used from new Scintillas. If dontIncrease = true, then the new document number isnt increased afterwards.
|
||||
//usefull for temporary but neccesary docs
|
||||
@ -368,7 +368,6 @@ private :
|
||||
// For backup system
|
||||
generic_string _backupFileName; // default: ""
|
||||
bool _isModified; // default: false
|
||||
//bool _deleteBackupNotification; // default: false
|
||||
|
||||
void updateTimeStamp();
|
||||
|
||||
|
@ -37,7 +37,8 @@
|
||||
|
||||
bool DocTabView::_hideTabBarStatus = false;
|
||||
|
||||
void DocTabView::addBuffer(BufferID buffer) {
|
||||
void DocTabView::addBuffer(BufferID buffer)
|
||||
{
|
||||
if (buffer == BUFFER_INVALID) //valid only
|
||||
return;
|
||||
if (this->getIndexByBuffer(buffer) != -1) //no duplicates
|
||||
@ -117,7 +118,8 @@ BufferID DocTabView::getBufferByIndex(int index) {
|
||||
return (BufferID)tie.lParam;
|
||||
}
|
||||
|
||||
void DocTabView::bufferUpdated(Buffer * buffer, int mask) {
|
||||
void DocTabView::bufferUpdated(Buffer * buffer, int mask)
|
||||
{
|
||||
int index = getIndexByBuffer(buffer->getID());
|
||||
if (index == -1)
|
||||
return;
|
||||
@ -126,16 +128,18 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask) {
|
||||
tie.lParam = -1;
|
||||
tie.mask = 0;
|
||||
|
||||
|
||||
if (mask & BufferChangeReadonly || mask & BufferChangeDirty) {
|
||||
if (mask & BufferChangeReadonly || mask & BufferChangeDirty)
|
||||
{
|
||||
tie.mask |= TCIF_IMAGE;
|
||||
tie.iImage = buffer->isDirty()?UNSAVED_IMG_INDEX:SAVED_IMG_INDEX;
|
||||
if (buffer->isReadOnly()) {
|
||||
if (buffer->isReadOnly())
|
||||
{
|
||||
tie.iImage = REDONLY_IMG_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & BufferChangeFilename) {
|
||||
if (mask & BufferChangeFilename)
|
||||
{
|
||||
tie.mask |= TCIF_TEXT;
|
||||
tie.pszText = (TCHAR *)buffer->getFileName();
|
||||
}
|
||||
@ -148,7 +152,8 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask) {
|
||||
::SendMessage(_hParent, WM_SIZE, 0, 0);
|
||||
}
|
||||
|
||||
void DocTabView::setBuffer(int index, BufferID id) {
|
||||
void DocTabView::setBuffer(int index, BufferID id)
|
||||
{
|
||||
if (index < 0 || index >= (int)_nbItem)
|
||||
return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user