2012-04-15 16:54:38 +00:00
// This file is part of Notepad++ project
// Copyright (C)2003 Don HO <don.h@free.fr>
2010-02-13 01:12:17 +00:00
//
2012-04-15 16:54:38 +00:00
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
2010-02-13 01:12:17 +00:00
//
2012-04-15 16:54:38 +00:00
// Note that the GPL places important restrictions on "derived works", yet
// it does not provide a detailed definition of that term. To avoid
// misunderstandings, we consider an application to constitute a
// "derivative work" for the purpose of this license if it does any of the
// following:
// 1. Integrates source code from Notepad++.
// 2. Integrates/includes/aggregates Notepad++ into a proprietary executable
// installer, such as those produced by InstallShield.
// 3. Links to a library or executes a program that does any of the above.
2010-02-13 01:12:17 +00:00
//
2012-04-15 16:54:38 +00:00
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2010-02-13 01:12:17 +00:00
# include "precompiledHeaders.h"
2010-03-26 00:22:14 +00:00
# include "Notepad_plus_Window.h"
2010-02-13 01:12:17 +00:00
# include "xmlMatchedTagsHighlighter.h"
2011-06-13 01:24:00 +00:00
# include "VerticalFileSwitcher.h"
2012-01-01 19:29:31 +00:00
# include "ProjectPanel.h"
2012-01-30 00:00:50 +00:00
# include "documentMap.h"
2013-06-14 19:37:20 +00:00
# include <stack>
2010-02-13 01:12:17 +00:00
BOOL Notepad_plus : : notify ( SCNotification * notification )
{
//Important, keep track of which element generated the message
bool isFromPrimary = ( _mainEditView . getHSelf ( ) = = notification - > nmhdr . hwndFrom | | _mainDocTab . getHSelf ( ) = = notification - > nmhdr . hwndFrom ) ;
bool isFromSecondary = ! isFromPrimary & & ( _subEditView . getHSelf ( ) = = notification - > nmhdr . hwndFrom | | _subDocTab . getHSelf ( ) = = notification - > nmhdr . hwndFrom ) ;
ScintillaEditView * notifyView = isFromPrimary ? & _mainEditView : & _subEditView ;
DocTabView * notifyDocTab = isFromPrimary ? & _mainDocTab : & _subDocTab ;
TBHDR * tabNotification = ( TBHDR * ) notification ;
switch ( notification - > nmhdr . code )
{
case SCN_MODIFIED :
{
static bool prevWasEdit = false ;
if ( notification - > modificationType & ( SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT ) )
{
2013-07-21 23:49:09 +00:00
_pEditView - > updateBeginEndSelectPosition ( notification - > modificationType & SC_MOD_INSERTTEXT , notification - > position , notification - > length ) ;
2010-02-13 01:12:17 +00:00
prevWasEdit = true ;
_linkTriggered = true ;
: : InvalidateRect ( notifyView - > getHSelf ( ) , NULL , TRUE ) ;
}
2014-03-27 01:30:31 +00:00
if ( notification - > modificationType & ( SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT | SC_PERFORMED_UNDO | SC_PERFORMED_REDO ) )
{
// for the backup system
_pEditView - > getCurrentBuffer ( ) - > setModifiedStatus ( true ) ;
}
2010-02-13 01:12:17 +00:00
if ( notification - > modificationType & SC_MOD_CHANGEFOLD )
{
2012-02-20 01:23:07 +00:00
if ( prevWasEdit )
{
2014-03-27 01:30:31 +00:00
notifyView - > foldChanged ( notification - > line , notification - > foldLevelNow , notification - > foldLevelPrev ) ;
2010-02-13 01:12:17 +00:00
prevWasEdit = false ;
}
}
else if ( ! ( notification - > modificationType & ( SC_MOD_DELETETEXT | SC_MOD_INSERTTEXT ) ) )
{
prevWasEdit = false ;
}
2014-03-27 01:30:31 +00:00
2010-02-13 01:12:17 +00:00
}
break ;
case SCN_SAVEPOINTREACHED :
case SCN_SAVEPOINTLEFT :
{
Buffer * buf = 0 ;
2014-03-29 00:01:33 +00:00
if ( isFromPrimary )
{
2010-02-13 01:12:17 +00:00
buf = _mainEditView . getCurrentBuffer ( ) ;
2014-03-29 00:01:33 +00:00
}
else if ( isFromSecondary )
{
2010-02-13 01:12:17 +00:00
buf = _subEditView . getCurrentBuffer ( ) ;
2014-03-29 00:01:33 +00:00
}
else
{
2010-02-13 01:12:17 +00:00
//Done by invisibleEditView?
BufferID id = BUFFER_INVALID ;
2014-12-09 23:16:48 +00:00
if ( notification - > nmhdr . hwndFrom = = _invisibleEditView . getHSelf ( ) )
{
2010-02-13 01:12:17 +00:00
id = MainFileManager - > getBufferFromDocument ( _invisibleEditView . execute ( SCI_GETDOCPOINTER ) ) ;
2014-12-09 23:16:48 +00:00
}
else if ( notification - > nmhdr . hwndFrom = = _fileEditView . getHSelf ( ) )
{
2010-02-13 01:12:17 +00:00
id = MainFileManager - > getBufferFromDocument ( _fileEditView . execute ( SCI_GETDOCPOINTER ) ) ;
2014-12-09 23:16:48 +00:00
}
else
{
2010-02-13 01:12:17 +00:00
break ; //wrong scintilla
}
2014-12-09 23:16:48 +00:00
if ( id ! = BUFFER_INVALID )
{
2010-02-13 01:12:17 +00:00
buf = MainFileManager - > getBufferByID ( id ) ;
2014-12-09 23:16:48 +00:00
}
else
{
2010-02-13 01:12:17 +00:00
break ;
}
}
2011-06-13 01:24:00 +00:00
bool isDirty = notification - > nmhdr . code = = SCN_SAVEPOINTLEFT ;
2014-12-09 23:16:48 +00:00
bool isSnapshotMode = NppParameters : : getInstance ( ) - > getNppGUI ( ) . isSnapshotMode ( ) ;
if ( isSnapshotMode & & ! isDirty )
{
bool canUndo = _pEditView - > execute ( SCI_CANUNDO ) = = TRUE ;
if ( ! canUndo & & buf - > isLoadedDirty ( ) )
isDirty = true ;
}
2011-06-13 01:24:00 +00:00
buf - > setDirty ( isDirty ) ;
break ;
}
2010-02-13 01:12:17 +00:00
case SCN_MODIFYATTEMPTRO :
// on fout rien
break ;
case SCN_KEY :
break ;
case TCN_TABDROPPEDOUTSIDE :
case TCN_TABDROPPED :
{
TabBarPlus * sender = reinterpret_cast < TabBarPlus * > ( notification - > nmhdr . idFrom ) ;
bool isInCtrlStat = ( : : GetKeyState ( VK_LCONTROL ) & 0x80000000 ) ! = 0 ;
if ( notification - > nmhdr . code = = TCN_TABDROPPEDOUTSIDE )
{
POINT p = sender - > getDraggingPoint ( ) ;
//It's the coordinate of screen, so we can call
//"WindowFromPoint" function without converting the point
HWND hWin = : : WindowFromPoint ( p ) ;
if ( hWin = = _pEditView - > getHSelf ( ) ) // In the same view group
{
if ( ! _tabPopupDropMenu . isCreated ( ) )
{
TCHAR goToView [ 32 ] = TEXT ( " Move to other view " ) ;
TCHAR cloneToView [ 32 ] = TEXT ( " Clone to other View " ) ;
vector < MenuItemUnit > itemUnitArray ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_GOTO_ANOTHER_VIEW , goToView ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_CLONE_TO_ANOTHER_VIEW , cloneToView ) ) ;
2014-02-16 20:55:42 +00:00
_tabPopupDropMenu . create ( _pPublicInterface - > getHSelf ( ) , itemUnitArray , _mainMenuHandle ) ;
2010-03-05 00:15:06 +00:00
_nativeLangSpeaker . changeLangTabDrapContextMenu ( _tabPopupDropMenu . getMenuHandle ( ) ) ;
2010-02-13 01:12:17 +00:00
}
_tabPopupDropMenu . display ( p ) ;
}
else if ( ( hWin = = _pNonDocTab - > getHSelf ( ) ) | |
( hWin = = _pNonEditView - > getHSelf ( ) ) ) // In the another view group
{
docGotoAnotherEditView ( isInCtrlStat ? TransferClone : TransferMove ) ;
2012-01-01 19:29:31 +00:00
} /*
else if ( ( hWin = = _pProjectPanel_1 - > getTreeHandle ( ) ) )
{
//printStr(TEXT("IN!!!"));
} */
2010-02-13 01:12:17 +00:00
else
{
RECT nppZone ;
2010-03-26 00:22:14 +00:00
: : GetWindowRect ( _pPublicInterface - > getHSelf ( ) , & nppZone ) ;
2010-02-13 01:12:17 +00:00
bool isInNppZone = ( ( ( p . x > = nppZone . left ) & & ( p . x < = nppZone . right ) ) & & ( p . y > = nppZone . top ) & & ( p . y < = nppZone . bottom ) ) ;
if ( isInNppZone )
{
// Do nothing
return TRUE ;
}
generic_string quotFileName = TEXT ( " \" " ) ;
quotFileName + = _pEditView - > getCurrentBuffer ( ) - > getFullPathName ( ) ;
quotFileName + = TEXT ( " \" " ) ;
COPYDATASTRUCT fileNamesData ;
fileNamesData . dwData = COPYDATA_FILENAMES ;
fileNamesData . lpData = ( void * ) quotFileName . c_str ( ) ;
fileNamesData . cbData = long ( quotFileName . length ( ) + 1 ) * ( sizeof ( TCHAR ) ) ;
HWND hWinParent = : : GetParent ( hWin ) ;
2015-03-14 22:55:03 +00:00
const rsize_t classNameBufferSize = MAX_PATH ;
TCHAR className [ classNameBufferSize ] ;
: : GetClassName ( hWinParent , className , classNameBufferSize ) ;
2010-03-26 00:22:14 +00:00
if ( lstrcmp ( className , _pPublicInterface - > getClassName ( ) ) = = 0 & & hWinParent ! = _pPublicInterface - > getHSelf ( ) ) // another Notepad++
2010-02-13 01:12:17 +00:00
{
int index = _pDocTab - > getCurrentTabIndex ( ) ;
BufferID bufferToClose = notifyDocTab - > getBufferByIndex ( index ) ;
Buffer * buf = MainFileManager - > getBufferByID ( bufferToClose ) ;
int iView = isFromPrimary ? MAIN_VIEW : SUB_VIEW ;
if ( buf - > isDirty ( ) )
{
2011-01-19 21:05:40 +00:00
generic_string msg , title ;
_nativeLangSpeaker . messageBox ( " CannotMoveDoc " ,
_pPublicInterface - > getHSelf ( ) ,
TEXT ( " Document is modified, save it then try again. " ) ,
TEXT ( " Move to new Notepad++ Instance " ) ,
MB_OK ) ;
2010-02-13 01:12:17 +00:00
}
else
{
: : SendMessage ( hWinParent , NPPM_INTERNAL_SWITCHVIEWFROMHWND , 0 , ( LPARAM ) hWin ) ;
2010-03-26 00:22:14 +00:00
: : SendMessage ( hWinParent , WM_COPYDATA , ( WPARAM ) _pPublicInterface - > getHinst ( ) , ( LPARAM ) & fileNamesData ) ;
2010-02-13 01:12:17 +00:00
if ( ! isInCtrlStat )
{
fileClose ( bufferToClose , iView ) ;
if ( noOpenedDoc ( ) )
2010-03-26 00:22:14 +00:00
: : SendMessage ( _pPublicInterface - > getHSelf ( ) , WM_CLOSE , 0 , 0 ) ;
2010-02-13 01:12:17 +00:00
}
}
}
else // Not Notepad++, we open it here
{
docOpenInNewInstance ( isInCtrlStat ? TransferClone : TransferMove , p . x , p . y ) ;
}
}
}
//break;
sender - > resetDraggingPoint ( ) ;
return TRUE ;
}
case TCN_TABDELETE :
{
int index = tabNotification - > tabOrigin ;
BufferID bufferToClose = notifyDocTab - > getBufferByIndex ( index ) ;
Buffer * buf = MainFileManager - > getBufferByID ( bufferToClose ) ;
int iView = isFromPrimary ? MAIN_VIEW : SUB_VIEW ;
2014-04-03 00:18:47 +00:00
if ( buf - > isDirty ( ) )
{
2010-02-13 01:12:17 +00:00
activateBuffer ( bufferToClose , iView ) ;
}
2014-04-03 00:18:47 +00:00
fileClose ( bufferToClose , iView ) ;
2010-02-13 01:12:17 +00:00
break ;
}
case TCN_SELCHANGE :
{
int iView = - 1 ;
if ( notification - > nmhdr . hwndFrom = = _mainDocTab . getHSelf ( ) )
{
iView = MAIN_VIEW ;
}
else if ( notification - > nmhdr . hwndFrom = = _subDocTab . getHSelf ( ) )
{
iView = SUB_VIEW ;
}
else
{
break ;
}
switchEditViewTo ( iView ) ;
BufferID bufid = _pDocTab - > getBufferByIndex ( _pDocTab - > getCurrentTabIndex ( ) ) ;
if ( bufid ! = BUFFER_INVALID )
activateBuffer ( bufid , iView ) ;
break ;
}
case NM_CLICK :
{
if ( notification - > nmhdr . hwndFrom = = _statusBar . getHSelf ( ) )
{
LPNMMOUSE lpnm = ( LPNMMOUSE ) notification ;
if ( lpnm - > dwItemSpec = = DWORD ( STATUSBAR_TYPING_MODE ) )
{
bool isOverTypeMode = ( _pEditView - > execute ( SCI_GETOVERTYPE ) ! = 0 ) ;
_pEditView - > execute ( SCI_SETOVERTYPE , ! isOverTypeMode ) ;
_statusBar . setText ( ( _pEditView - > execute ( SCI_GETOVERTYPE ) ) ? TEXT ( " OVR " ) : TEXT ( " INS " ) , STATUSBAR_TYPING_MODE ) ;
}
}
2014-03-31 01:01:54 +00:00
else if ( notification - > nmhdr . hwndFrom = = _mainDocTab . getHSelf ( ) & & _activeView = = SUB_VIEW )
2010-02-13 01:12:17 +00:00
{
2014-05-08 20:48:03 +00:00
bool isSnapshotMode = NppParameters : : getInstance ( ) - > getNppGUI ( ) . isSnapshotMode ( ) ;
2014-04-13 01:31:02 +00:00
if ( isSnapshotMode )
2014-04-10 18:16:11 +00:00
{
// Before switching off, synchronize backup file
MainFileManager - > backupCurrentBuffer ( ) ;
}
2014-03-31 01:01:54 +00:00
// Switch off
2010-02-13 01:12:17 +00:00
switchEditViewTo ( MAIN_VIEW ) ;
}
2014-03-31 01:01:54 +00:00
else if ( notification - > nmhdr . hwndFrom = = _subDocTab . getHSelf ( ) & & _activeView = = MAIN_VIEW )
2010-02-13 01:12:17 +00:00
{
2014-05-08 20:48:03 +00:00
bool isSnapshotMode = NppParameters : : getInstance ( ) - > getNppGUI ( ) . isSnapshotMode ( ) ;
2014-04-13 01:31:02 +00:00
if ( isSnapshotMode )
2014-04-10 18:16:11 +00:00
{
// Before switching off, synchronize backup file
MainFileManager - > backupCurrentBuffer ( ) ;
}
2014-03-31 01:01:54 +00:00
// Switch off
2010-02-13 01:12:17 +00:00
switchEditViewTo ( SUB_VIEW ) ;
}
break ;
}
case NM_DBLCLK :
{
if ( notification - > nmhdr . hwndFrom = = _statusBar . getHSelf ( ) )
{
LPNMMOUSE lpnm = ( LPNMMOUSE ) notification ;
if ( lpnm - > dwItemSpec = = DWORD ( STATUSBAR_CUR_POS ) )
{
bool isFirstTime = ! _goToLineDlg . isCreated ( ) ;
2010-03-05 00:15:06 +00:00
_goToLineDlg . doDialog ( _nativeLangSpeaker . isRTL ( ) ) ;
2010-02-13 01:12:17 +00:00
if ( isFirstTime )
2010-03-05 00:15:06 +00:00
_nativeLangSpeaker . changeDlgLang ( _goToLineDlg . getHSelf ( ) , " GoToLine " ) ;
2010-02-13 01:12:17 +00:00
}
2010-09-19 01:27:41 +00:00
else if ( lpnm - > dwItemSpec = = DWORD ( STATUSBAR_DOC_SIZE ) )
{
command ( IDM_VIEW_SUMMARY ) ;
}
2010-02-13 01:12:17 +00:00
}
break ;
}
case NM_RCLICK :
{
2013-05-01 15:43:51 +00:00
POINT p ;
: : GetCursorPos ( & p ) ;
2010-02-13 01:12:17 +00:00
if ( notification - > nmhdr . hwndFrom = = _mainDocTab . getHSelf ( ) )
{
switchEditViewTo ( MAIN_VIEW ) ;
}
else if ( notification - > nmhdr . hwndFrom = = _subDocTab . getHSelf ( ) )
{
switchEditViewTo ( SUB_VIEW ) ;
}
2011-06-22 00:12:36 +00:00
else if ( _pFileSwitcherPanel & & notification - > nmhdr . hwndFrom = = _pFileSwitcherPanel - > getHSelf ( ) )
{
// Already switched, so do nothing here.
2013-05-01 15:43:51 +00:00
if ( _pFileSwitcherPanel - > nbSelectedFiles ( ) > 1 )
{
if ( ! _fileSwitcherMultiFilePopupMenu . isCreated ( ) )
{
vector < MenuItemUnit > itemUnitArray ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILESWITCHER_FILESCLOSE , TEXT ( " Close Selected files " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILESWITCHER_FILESCLOSEOTHERS , TEXT ( " Close others files " ) ) ) ;
_fileSwitcherMultiFilePopupMenu . create ( _pPublicInterface - > getHSelf ( ) , itemUnitArray ) ;
_nativeLangSpeaker . changeLangTabContextMenu ( _fileSwitcherMultiFilePopupMenu . getMenuHandle ( ) ) ;
}
_fileSwitcherMultiFilePopupMenu . display ( p ) ;
return TRUE ;
}
2011-06-22 00:12:36 +00:00
}
2010-02-13 01:12:17 +00:00
else // From tool bar or Status Bar
return TRUE ;
//break;
if ( ! _tabPopupMenu . isCreated ( ) )
{
vector < MenuItemUnit > itemUnitArray ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_CLOSE , TEXT ( " Close " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_CLOSEALL_BUT_CURRENT , TEXT ( " Close All BUT This " ) ) ) ;
2013-08-03 23:40:07 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_CLOSEALL_TOLEFT , TEXT ( " Close All to the Left " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_CLOSEALL_TORIGHT , TEXT ( " Close All to the Right " ) ) ) ;
2010-02-13 01:12:17 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_SAVE , TEXT ( " Save " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_SAVEAS , TEXT ( " Save As... " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_RENAME , TEXT ( " Rename " ) ) ) ;
2012-12-07 01:33:08 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_DELETE , TEXT ( " Move to Recycle Bin " ) ) ) ;
2012-06-10 14:45:54 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_RELOAD , TEXT ( " Reload " ) ) ) ;
2010-02-13 01:12:17 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_PRINT , TEXT ( " Print " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( 0 , NULL ) ) ;
2013-12-08 13:52:49 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_OPEN_FOLDER , TEXT ( " Open Containing Folder in Explorer " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_FILE_OPEN_CMD , TEXT ( " Open Containing Folder in cmd " ) ) ) ;
2013-12-07 01:43:35 +00:00
itemUnitArray . push_back ( MenuItemUnit ( 0 , NULL ) ) ;
2010-02-13 01:12:17 +00:00
itemUnitArray . push_back ( MenuItemUnit ( IDM_EDIT_SETREADONLY , TEXT ( " Read-Only " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_EDIT_CLEARREADONLY , TEXT ( " Clear Read-Only Flag " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( 0 , NULL ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_EDIT_FULLPATHTOCLIP , TEXT ( " Full File Path to Clipboard " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_EDIT_FILENAMETOCLIP , TEXT ( " Filename to Clipboard " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_EDIT_CURRENTDIRTOCLIP , TEXT ( " Current Dir. Path to Clipboard " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( 0 , NULL ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_GOTO_ANOTHER_VIEW , TEXT ( " Move to Other View " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_CLONE_TO_ANOTHER_VIEW , TEXT ( " Clone to Other View " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_GOTO_NEW_INSTANCE , TEXT ( " Move to New Instance " ) ) ) ;
itemUnitArray . push_back ( MenuItemUnit ( IDM_VIEW_LOAD_IN_NEW_INSTANCE , TEXT ( " Open in New Instance " ) ) ) ;
2010-03-26 00:22:14 +00:00
_tabPopupMenu . create ( _pPublicInterface - > getHSelf ( ) , itemUnitArray ) ;
2010-03-05 00:15:06 +00:00
_nativeLangSpeaker . changeLangTabContextMenu ( _tabPopupMenu . getMenuHandle ( ) ) ;
2010-02-13 01:12:17 +00:00
}
bool isEnable = ( ( : : GetMenuState ( _mainMenuHandle , IDM_FILE_SAVE , MF_BYCOMMAND ) & MF_DISABLED ) = = 0 ) ;
_tabPopupMenu . enableItem ( IDM_FILE_SAVE , isEnable ) ;
Buffer * buf = _pEditView - > getCurrentBuffer ( ) ;
bool isUserReadOnly = buf - > getUserReadOnly ( ) ;
_tabPopupMenu . checkItem ( IDM_EDIT_SETREADONLY , isUserReadOnly ) ;
bool isSysReadOnly = buf - > getFileReadOnly ( ) ;
_tabPopupMenu . enableItem ( IDM_EDIT_SETREADONLY , ! isSysReadOnly ) ;
_tabPopupMenu . enableItem ( IDM_EDIT_CLEARREADONLY , isSysReadOnly ) ;
bool isFileExisting = PathFileExists ( buf - > getFullPathName ( ) ) ! = FALSE ;
_tabPopupMenu . enableItem ( IDM_FILE_DELETE , isFileExisting ) ;
_tabPopupMenu . enableItem ( IDM_FILE_RENAME , isFileExisting ) ;
bool isDirty = buf - > isDirty ( ) ;
bool isUntitled = buf - > isUntitled ( ) ;
_tabPopupMenu . enableItem ( IDM_VIEW_GOTO_NEW_INSTANCE , ! ( isDirty | | isUntitled ) ) ;
_tabPopupMenu . enableItem ( IDM_VIEW_LOAD_IN_NEW_INSTANCE , ! ( isDirty | | isUntitled ) ) ;
_tabPopupMenu . display ( p ) ;
return TRUE ;
}
case SCN_MARGINCLICK :
{
if ( notification - > nmhdr . hwndFrom = = _mainEditView . getHSelf ( ) )
switchEditViewTo ( MAIN_VIEW ) ;
else if ( notification - > nmhdr . hwndFrom = = _subEditView . getHSelf ( ) )
switchEditViewTo ( SUB_VIEW ) ;
2012-02-20 01:23:07 +00:00
int lineClick = int ( _pEditView - > execute ( SCI_LINEFROMPOSITION , notification - > position ) ) ;
2010-02-13 01:12:17 +00:00
2012-02-20 01:23:07 +00:00
if ( notification - > margin = = ScintillaEditView : : _SC_MARGE_FOLDER )
2010-02-13 01:12:17 +00:00
{
_pEditView - > marginClick ( notification - > position , notification - > modifiers ) ;
2012-02-20 01:23:07 +00:00
if ( _pDocMap )
_pDocMap - > fold ( lineClick , _pEditView - > isFolded ( lineClick ) ) ;
2010-02-13 01:12:17 +00:00
}
else if ( ( notification - > margin = = ScintillaEditView : : _SC_MARGE_SYBOLE ) & & ! notification - > modifiers )
{
if ( ! _pEditView - > markerMarginClick ( lineClick ) )
bookmarkToggle ( lineClick ) ;
}
break ;
}
2012-02-20 01:23:07 +00:00
case SCN_FOLDINGSTATECHANGED :
{
if ( ( notification - > nmhdr . hwndFrom = = _mainEditView . getHSelf ( ) )
| | ( notification - > nmhdr . hwndFrom = = _subEditView . getHSelf ( ) ) )
{
int lineClicked = notification - > line ;
2012-05-25 23:40:44 +00:00
if ( ! _isFolding )
{
int urlAction = ( NppParameters : : getInstance ( ) ) - > getNppGUI ( ) . _styleURL ;
if ( ( urlAction = = 1 ) | | ( urlAction = = 2 ) )
2012-10-19 00:20:40 +00:00
addHotSpot ( ) ;
2012-05-25 23:40:44 +00:00
}
2012-02-20 01:23:07 +00:00
if ( _pDocMap )
_pDocMap - > fold ( lineClicked , _pEditView - > isFolded ( lineClicked ) ) ;
}
return TRUE ;
}
2013-09-02 09:05:37 +00:00
2010-02-13 01:12:17 +00:00
case SCN_CHARADDED :
{
2013-09-03 00:58:59 +00:00
const NppGUI & nppGui = NppParameters : : getInstance ( ) - > getNppGUI ( ) ;
bool indentMaintain = nppGui . _maitainIndent ;
2012-08-08 23:39:03 +00:00
if ( indentMaintain )
2014-11-12 02:14:45 +00:00
maintainIndentation ( static_cast < TCHAR > ( notification - > ch ) ) ;
2013-09-02 09:05:37 +00:00
2010-02-13 01:12:17 +00:00
AutoCompletion * autoC = isFromPrimary ? & _autoCompleteMain : & _autoCompleteSub ;
2014-12-23 22:03:36 +00:00
bool isColumnMode = _pEditView - > execute ( SCI_GETSELECTIONS ) > 1 ; // Multi-Selection || Column mode)
if ( nppGui . _matchedPairConf . hasAnyPairsPair ( ) & & ! isColumnMode )
2013-09-03 00:58:59 +00:00
autoC - > insertMatchedChars ( notification - > ch , nppGui . _matchedPairConf ) ;
2010-02-13 01:12:17 +00:00
autoC - > update ( notification - > ch ) ;
2013-09-02 09:05:37 +00:00
2010-02-13 01:12:17 +00:00
break ;
}
case SCN_DOUBLECLICK :
{
2015-03-14 22:55:03 +00:00
if ( notification - > modifiers = = SCMOD_CTRL )
2013-06-08 23:17:59 +00:00
{
const NppGUI & nppGUI = NppParameters : : getInstance ( ) - > getNppGUI ( ) ;
2013-06-14 19:37:20 +00:00
std : : string bufstring ;
2015-02-13 23:30:34 +00:00
2013-06-14 19:37:20 +00:00
unsigned int position_of_click ;
2015-02-13 23:30:34 +00:00
// For some reason Ctrl+DoubleClick on an empty line means that notification->position == 1.
// In that case we use SCI_GETCURRENTPOS to get the position.
if ( notification - > position ! = - 1 )
position_of_click = notification - > position ;
else
position_of_click = int ( _pEditView - > execute ( SCI_GETCURRENTPOS ) ) ;
2013-06-08 23:17:59 +00:00
2013-06-14 19:37:20 +00:00
// Anonymous scope to limit use of the buf pointer (much easier to deal with std::string).
2013-06-08 23:17:59 +00:00
{
2013-06-14 19:37:20 +00:00
char * buf ;
int length ;
2015-03-14 22:55:03 +00:00
if ( nppGUI . _delimiterSelectionOnEntireDocument )
2013-06-08 23:17:59 +00:00
{
2013-06-14 19:37:20 +00:00
// Get entire document.
length = notifyView - > execute ( SCI_GETLENGTH ) ;
buf = new char [ length + 1 ] ;
notifyView - > execute ( SCI_GETTEXT , ( LPARAM ) ( length + 1 ) , ( WPARAM ) buf ) ;
}
else
{
// Get single line.
length = notifyView - > execute ( SCI_GETCURLINE ) ;
buf = new char [ length + 1 ] ;
notifyView - > execute ( SCI_GETCURLINE , ( WPARAM ) length , ( LPARAM ) buf ) ;
// Compute the position of the click (relative to the beginning of the line).
const int line_position = notifyView - > execute ( SCI_POSITIONFROMLINE , notifyView - > getCurrentLineNumber ( ) ) ;
2015-02-13 23:30:34 +00:00
position_of_click = position_of_click - line_position ;
2013-06-08 23:17:59 +00:00
}
2013-06-14 19:37:20 +00:00
bufstring = buf ;
2013-06-08 23:17:59 +00:00
delete [ ] buf ;
}
2013-06-14 19:37:20 +00:00
int leftmost_position = - 1 ;
2013-06-08 23:17:59 +00:00
int rightmost_position = - 1 ;
2013-06-14 19:37:20 +00:00
2015-03-14 22:55:03 +00:00
if ( nppGUI . _rightmostDelimiter = = nppGUI . _leftmostDelimiter )
2013-06-08 23:17:59 +00:00
{
2013-06-14 19:37:20 +00:00
// If the delimiters are the same (e.g. they are both a quotation mark), choose the ones
// which are closest to the clicked position.
2015-03-14 22:55:03 +00:00
for ( int i = position_of_click ; i > = 0 ; - - i )
2013-06-08 23:17:59 +00:00
{
2015-03-14 22:55:03 +00:00
if ( bufstring . at ( i ) = = nppGUI . _leftmostDelimiter )
2013-06-14 19:37:20 +00:00
{
2013-07-08 20:14:02 +00:00
// Respect escaped quotation marks.
2015-03-14 22:55:03 +00:00
if ( nppGUI . _leftmostDelimiter = = ' " ' )
2013-07-08 20:14:02 +00:00
{
2015-03-14 22:55:03 +00:00
if ( ! ( i > 0 & & bufstring . at ( i - 1 ) = = ' \\ ' ) )
2013-07-08 20:14:02 +00:00
{
leftmost_position = i ;
break ;
}
}
else
{
leftmost_position = i ;
break ;
}
2013-06-14 19:37:20 +00:00
}
2013-06-08 23:17:59 +00:00
}
2015-03-14 22:55:03 +00:00
if ( leftmost_position = = - 1 )
2013-06-14 19:37:20 +00:00
break ;
2013-06-08 23:17:59 +00:00
2013-06-14 19:37:20 +00:00
// Scan for right delimiter.
2015-03-14 22:55:03 +00:00
for ( unsigned int i = position_of_click ; i < bufstring . length ( ) ; + + i )
2013-06-14 19:37:20 +00:00
{
2015-03-14 22:55:03 +00:00
if ( bufstring . at ( i ) = = nppGUI . _rightmostDelimiter )
2013-06-14 19:37:20 +00:00
{
2013-07-08 20:14:02 +00:00
// Respect escaped quotation marks.
2015-03-14 22:55:03 +00:00
if ( nppGUI . _rightmostDelimiter = = ' " ' )
2013-07-08 20:14:02 +00:00
{
2015-03-14 22:55:03 +00:00
if ( ! ( i > 0 & & bufstring . at ( i - 1 ) = = ' \\ ' ) )
2013-07-08 20:14:02 +00:00
{
rightmost_position = i ;
break ;
}
}
else
{
rightmost_position = i ;
break ;
}
2013-06-14 19:37:20 +00:00
}
}
2013-06-08 23:17:59 +00:00
}
else
{
2013-06-14 19:37:20 +00:00
// Find matching pairs of delimiters (e.g. parantheses).
// The pair where the distance from the left delimiter to position_of_click is at a minimum is the one we're looking for.
// Of course position_of_click must lie between the delimiters.
// This logic is required to handle cases like this:
// (size_t i = function(); i < _buffers.size(); i++)
std : : stack < unsigned int > leftmost_delimiter_positions ;
2015-03-14 22:55:03 +00:00
for ( unsigned int i = 0 ; i < bufstring . length ( ) ; + + i )
2013-06-14 19:37:20 +00:00
{
2015-03-14 22:55:03 +00:00
if ( bufstring . at ( i ) = = nppGUI . _leftmostDelimiter )
2013-06-14 19:37:20 +00:00
leftmost_delimiter_positions . push ( i ) ;
2015-03-14 22:55:03 +00:00
else if ( bufstring . at ( i ) = = nppGUI . _rightmostDelimiter & & ! leftmost_delimiter_positions . empty ( ) )
2013-06-14 19:37:20 +00:00
{
unsigned int matching_leftmost = leftmost_delimiter_positions . top ( ) ;
leftmost_delimiter_positions . pop ( ) ;
// We have either 1) chosen neither the left- or rightmost position, or 2) chosen both left- and rightmost position.
assert ( ( leftmost_position = = - 1 & & rightmost_position = = - 1 ) | | ( leftmost_position > = 0 & & rightmost_position > = 0 ) ) ;
// Note: cast of leftmost_position to unsigned int is safe, since if leftmost_position is not -1 then it is guaranteed to be positive.
// If it was possible, leftmost_position and rightmost_position should be of type optional<unsigned int>.
2015-03-14 22:55:03 +00:00
if ( matching_leftmost < = position_of_click & & i > = position_of_click & & ( leftmost_position = = - 1 | | matching_leftmost > ( unsigned int ) leftmost_position ) )
2013-06-14 19:37:20 +00:00
{
leftmost_position = matching_leftmost ;
rightmost_position = i ;
}
}
}
2013-06-08 23:17:59 +00:00
}
2013-06-14 19:37:20 +00:00
// Set selection to the position we found (if any).
2015-03-14 22:55:03 +00:00
if ( rightmost_position ! = - 1 & & leftmost_position ! = - 1 )
2013-06-14 19:37:20 +00:00
{
2015-03-14 22:55:03 +00:00
if ( nppGUI . _delimiterSelectionOnEntireDocument )
2013-06-14 19:37:20 +00:00
{
notifyView - > execute ( SCI_SETCURRENTPOS , rightmost_position ) ;
notifyView - > execute ( SCI_SETANCHOR , leftmost_position + 1 ) ;
}
else
{
const int line_position = notifyView - > execute ( SCI_POSITIONFROMLINE , notifyView - > getCurrentLineNumber ( ) ) ;
notifyView - > execute ( SCI_SETCURRENTPOS , line_position + rightmost_position ) ;
notifyView - > execute ( SCI_SETANCHOR , line_position + leftmost_position + 1 ) ;
}
}
2013-06-08 23:17:59 +00:00
}
else if ( _isHotspotDblClicked )
2010-02-13 01:12:17 +00:00
{
int pos = notifyView - > execute ( SCI_GETCURRENTPOS ) ;
notifyView - > execute ( SCI_SETCURRENTPOS , pos ) ;
notifyView - > execute ( SCI_SETANCHOR , pos ) ;
_isHotspotDblClicked = false ;
}
}
break ;
case SCN_UPDATEUI :
{
NppParameters * nppParam = NppParameters : : getInstance ( ) ;
2013-09-02 08:30:29 +00:00
// replacement for obsolete custom SCN_SCROLLED
if ( notification - > updated & SC_UPDATE_V_SCROLL )
{
int urlAction = ( NppParameters : : getInstance ( ) ) - > getNppGUI ( ) . _styleURL ;
if ( ( urlAction = = 1 ) | | ( urlAction = = 2 ) )
addHotSpot ( ) ;
}
2010-02-13 01:12:17 +00:00
// if it's searching/replacing, then do nothing
if ( nppParam - > _isFindReplacing )
break ;
if ( notification - > nmhdr . hwndFrom ! = _pEditView - > getHSelf ( ) )
break ;
braceMatch ( ) ;
NppGUI & nppGui = ( NppGUI & ) nppParam - > getNppGUI ( ) ;
if ( nppGui . _enableTagsMatchHilite )
{
XmlMatchedTagsHighlighter xmlTagMatchHiliter ( _pEditView ) ;
xmlTagMatchHiliter . tagMatch ( nppGui . _enableTagAttrsHilite ) ;
}
if ( nppGui . _enableSmartHilite )
{
if ( nppGui . _disableSmartHiliteTmp )
nppGui . _disableSmartHiliteTmp = false ;
else
_smartHighlighter . highlightView ( notifyView ) ;
}
updateStatusBar ( ) ;
AutoCompletion * autoC = isFromPrimary ? & _autoCompleteMain : & _autoCompleteSub ;
autoC - > update ( 0 ) ;
2012-01-30 00:00:50 +00:00
2010-02-13 01:12:17 +00:00
break ;
}
case TTN_GETDISPINFO :
{
try {
LPTOOLTIPTEXT lpttt = ( LPTOOLTIPTEXT ) notification ;
//Joce's fix
lpttt - > hinst = NULL ;
POINT p ;
: : GetCursorPos ( & p ) ;
2010-03-26 00:22:14 +00:00
: : ScreenToClient ( _pPublicInterface - > getHSelf ( ) , & p ) ;
HWND hWin = : : RealChildWindowFromPoint ( _pPublicInterface - > getHSelf ( ) , p ) ;
2010-02-13 01:12:17 +00:00
const int tipMaxLen = 1024 ;
static TCHAR docTip [ tipMaxLen ] ;
docTip [ 0 ] = ' \0 ' ;
generic_string tipTmp ( TEXT ( " " ) ) ;
int id = int ( lpttt - > hdr . idFrom ) ;
if ( hWin = = _rebarTop . getHSelf ( ) )
{
getNameStrFromCmd ( id , tipTmp ) ;
if ( tipTmp . length ( ) > = 80 )
return FALSE ;
lstrcpy ( lpttt - > szText , tipTmp . c_str ( ) ) ;
return TRUE ;
}
else if ( hWin = = _mainDocTab . getHSelf ( ) )
{
BufferID idd = _mainDocTab . getBufferByIndex ( id ) ;
Buffer * buf = MainFileManager - > getBufferByID ( idd ) ;
tipTmp = buf - > getFullPathName ( ) ;
if ( tipTmp . length ( ) > = tipMaxLen )
return FALSE ;
lstrcpy ( docTip , tipTmp . c_str ( ) ) ;
lpttt - > lpszText = docTip ;
return TRUE ;
}
else if ( hWin = = _subDocTab . getHSelf ( ) )
{
BufferID idd = _subDocTab . getBufferByIndex ( id ) ;
Buffer * buf = MainFileManager - > getBufferByID ( idd ) ;
tipTmp = buf - > getFullPathName ( ) ;
if ( tipTmp . length ( ) > = tipMaxLen )
return FALSE ;
lstrcpy ( docTip , tipTmp . c_str ( ) ) ;
lpttt - > lpszText = docTip ;
return TRUE ;
}
else
{
return FALSE ;
}
} catch ( . . . ) {
//printStr(TEXT("ToolTip crash is caught!"));
}
}
break ;
case SCN_ZOOM :
break ;
case SCN_MACRORECORD :
2010-10-05 21:33:37 +00:00
_macro . push_back ( recordedMacroStep ( notification - > message , notification - > wParam , notification - > lParam , _pEditView - > execute ( SCI_GETCODEPAGE ) ) ) ;
2010-02-13 01:12:17 +00:00
break ;
case SCN_PAINTED :
{
2012-06-30 01:30:00 +00:00
//--FLS: ViewMoveAtWrappingDisableFix: Disable wrapping messes up visible lines. Therefore save view position before in IDM_VIEW_WRAP and restore after SCN_PAINTED, as doc. says
if ( _mainEditView . isWrapRestoreNeeded ( ) )
{
_mainEditView . restoreCurrentPos ( ) ;
_mainEditView . setWrapRestoreNeeded ( false ) ;
}
if ( _subEditView . isWrapRestoreNeeded ( ) )
{
_subEditView . restoreCurrentPos ( ) ;
_subEditView . setWrapRestoreNeeded ( false ) ;
}
2010-02-13 01:12:17 +00:00
notifyView - > updateLineNumberWidth ( ) ;
if ( _syncInfo . doSync ( ) )
doSynScorll ( HWND ( notification - > nmhdr . hwndFrom ) ) ;
NppParameters * nppParam = NppParameters : : getInstance ( ) ;
// if it's searching/replacing, then do nothing
2012-10-19 00:20:40 +00:00
if ( ( _linkTriggered & & ! nppParam - > _isFindReplacing ) | | notification - > wParam = = LINKTRIGGERED )
2010-02-13 01:12:17 +00:00
{
int urlAction = ( NppParameters : : getInstance ( ) ) - > getNppGUI ( ) . _styleURL ;
if ( ( urlAction = = 1 ) | | ( urlAction = = 2 ) )
2012-10-19 00:20:40 +00:00
addHotSpot ( ) ;
2010-02-13 01:12:17 +00:00
_linkTriggered = false ;
}
2012-03-08 01:02:12 +00:00
if ( _pDocMap )
{
2012-03-14 02:07:45 +00:00
_pDocMap - > wrapMap ( ) ;
_pDocMap - > scrollMap ( ) ;
2012-03-08 01:02:12 +00:00
}
2010-02-13 01:12:17 +00:00
break ;
}
case SCN_HOTSPOTDOUBLECLICK :
{
2012-10-07 17:46:22 +00:00
notifyView - > execute ( SCI_SETWORDCHARS , 0 , ( LPARAM ) " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-+.,:?&@=/%#() " ) ;
2010-02-13 01:12:17 +00:00
int pos = notifyView - > execute ( SCI_GETCURRENTPOS ) ;
int startPos = static_cast < int > ( notifyView - > execute ( SCI_WORDSTARTPOSITION , pos , false ) ) ;
int endPos = static_cast < int > ( notifyView - > execute ( SCI_WORDENDPOSITION , pos , false ) ) ;
notifyView - > execute ( SCI_SETTARGETSTART , startPos ) ;
notifyView - > execute ( SCI_SETTARGETEND , endPos ) ;
2010-02-21 18:17:54 +00:00
int posFound = notifyView - > execute ( SCI_SEARCHINTARGET , strlen ( URL_REG_EXPR ) , ( LPARAM ) URL_REG_EXPR ) ;
2014-03-05 01:06:49 +00:00
if ( posFound ! = - 2 )
2010-02-13 01:12:17 +00:00
{
2014-03-05 01:06:49 +00:00
if ( posFound ! = - 1 )
{
startPos = int ( notifyView - > execute ( SCI_GETTARGETSTART ) ) ;
endPos = int ( notifyView - > execute ( SCI_GETTARGETEND ) ) ;
}
2010-02-13 01:12:17 +00:00
2014-03-05 01:06:49 +00:00
// Prevent buffer overflow in getGenericText().
if ( endPos - startPos > 2 * MAX_PATH )
endPos = startPos + 2 * MAX_PATH ;
2012-08-22 09:39:02 +00:00
2014-03-05 01:06:49 +00:00
TCHAR currentWord [ 2 * MAX_PATH ] ;
2012-08-22 09:39:02 +00:00
2014-03-05 01:06:49 +00:00
notifyView - > getGenericText ( currentWord , MAX_PATH * 2 , startPos , endPos ) ;
2010-02-13 01:12:17 +00:00
2014-03-05 01:06:49 +00:00
// This treatment would fail on some valid URLs where there's actually supposed to be a comma or parenthesis at the end.
int lastCharIndex = _tcsnlen ( currentWord , MAX_PATH * 2 ) - 1 ;
if ( lastCharIndex > = 0 & & ( currentWord [ lastCharIndex ] = = ' , ' | | currentWord [ lastCharIndex ] = = ' ) ' | | currentWord [ lastCharIndex ] = = ' ( ' ) )
currentWord [ lastCharIndex ] = ' \0 ' ;
2012-10-07 17:46:22 +00:00
2014-03-05 01:06:49 +00:00
: : ShellExecute ( _pPublicInterface - > getHSelf ( ) , TEXT ( " open " ) , currentWord , NULL , NULL , SW_SHOW ) ;
_isHotspotDblClicked = true ;
notifyView - > execute ( SCI_SETCHARSDEFAULT ) ;
}
2010-02-13 01:12:17 +00:00
break ;
}
case SCN_NEEDSHOWN :
{
int begin = notifyView - > execute ( SCI_LINEFROMPOSITION , notification - > position ) ;
int end = notifyView - > execute ( SCI_LINEFROMPOSITION , notification - > position + notification - > length ) ;
int firstLine = begin < end ? begin : end ;
int lastLine = begin > end ? begin : end ;
2013-07-08 00:12:50 +00:00
for ( int line = firstLine ; line < = lastLine ; + + line )
{
2010-02-13 01:12:17 +00:00
notifyView - > execute ( SCI_ENSUREVISIBLE , line , 0 ) ;
}
break ;
}
case SCN_CALLTIPCLICK :
{
AutoCompletion * autoC = isFromPrimary ? & _autoCompleteMain : & _autoCompleteSub ;
autoC - > callTipClick ( notification - > position ) ;
break ;
}
case RBN_HEIGHTCHANGE :
{
2010-03-26 00:22:14 +00:00
SendMessage ( _pPublicInterface - > getHSelf ( ) , WM_SIZE , 0 , 0 ) ;
2010-02-13 01:12:17 +00:00
break ;
}
case RBN_CHEVRONPUSHED :
{
NMREBARCHEVRON * lpnm = ( NMREBARCHEVRON * ) notification ;
ReBar * notifRebar = & _rebarTop ;
if ( _rebarBottom . getHSelf ( ) = = lpnm - > hdr . hwndFrom )
notifRebar = & _rebarBottom ;
//If N++ ID, use proper object
switch ( lpnm - > wID ) {
case REBAR_BAR_TOOLBAR : {
POINT pt ;
pt . x = lpnm - > rc . left ;
pt . y = lpnm - > rc . bottom ;
ClientToScreen ( notifRebar - > getHSelf ( ) , & pt ) ;
_toolBar . doPopop ( pt ) ;
return TRUE ;
break ; }
}
//Else forward notification to window of rebarband
REBARBANDINFO rbBand ;
ZeroMemory ( & rbBand , REBARBAND_SIZE ) ;
rbBand . cbSize = REBARBAND_SIZE ;
rbBand . fMask = RBBIM_CHILD ;
: : SendMessage ( notifRebar - > getHSelf ( ) , RB_GETBANDINFO , lpnm - > uBand , ( LPARAM ) & rbBand ) ;
: : SendMessage ( rbBand . hwndChild , WM_NOTIFY , 0 , ( LPARAM ) lpnm ) ;
break ;
}
default :
break ;
}
return FALSE ;
}