diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64b13867..550bd618 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Your pull requests are welcome; however, they may not be accepted for various re 1. Respect Notepad++ coding style. 2. Make a single change per commit. 3. Make your modification compact - don't reformat source code in your request. It makes code review more difficult. -4. PR of reformating (changing of ws/TAB, line endings or coding style) of source code won't be accepted. Use issue trackers for your request instead. +4. PR of reformatting (changing of ws/TAB, line endings or coding style) of source code won't be accepted. Use issue trackers for your request instead. 5. Only bug-fix and feature request will be accepted. For the other things, I can run static code analysis tool myself. In short: The easier the code review is, the better the chance your pull request will get accepted. diff --git a/PowerEditor/bin/change.log b/PowerEditor/bin/change.log index e93dbb71..b67ed302 100644 --- a/PowerEditor/bin/change.log +++ b/PowerEditor/bin/change.log @@ -1,23 +1,12 @@ -Notepad++ v6.7.8.2 bug-fix: +Notepad++ v6.7.9 new features and bug-fix: -1. Disable Notepad++ updater (WinGup) under XP. - - -Notepad++ v6.7.8.1 bug-fix: - -1. Fix "Missing msvcr120.dll" message error (of WinGup). - - -Notepad++ v6.7.8 new features and bug-fixes: - -1. Fix an annoying regression about message "The buffer passed to GetFullPathName was too small!". -2. Update WinGup to version 3.0 which has SSL support and customizable User-Agent. -3. Improve sort lines performance greatly. -4. Fix tabbar close button usability issue (too small) on a high resolution laptop (Surface Pro 3). -5. Fix Settings on cloud - Google drive detection error. -6. Hiding tab bar via command line won't make hidden tab setting be saved in the next session. -7. Fix a bug of "Jump to next indicator" command. -8. Fix "File Status auto-detection" settings bug. +1. Upgrade Scintilla to v3.56. +2. Add Language and EOL conversion context menu on status bar. +3. Enhance sort lines feature: Add lexicographic and numeric (integer and real) sorting with ascending and descending order. +4. Add new feature which launches a new instance with administrator privilege to save the protected file. +5. Fix the context menu not working problem after doing find in files action. +6. Improve copy (to clipboard) in found results panel. +7. Improve find in files modal dialog. diff --git a/PowerEditor/installer/APIs/javascript.xml b/PowerEditor/installer/APIs/javascript.xml index f0abc665..79350213 100644 --- a/PowerEditor/installer/APIs/javascript.xml +++ b/PowerEditor/installer/APIs/javascript.xml @@ -5,6 +5,7 @@ + @@ -75,6 +76,7 @@ + @@ -130,6 +132,7 @@ + @@ -169,6 +172,7 @@ + @@ -188,15 +192,24 @@ + + + + + + + + + @@ -219,6 +232,9 @@ + + + @@ -242,6 +258,7 @@ + @@ -260,6 +277,7 @@ + @@ -271,6 +289,7 @@ + @@ -295,6 +314,8 @@ + + @@ -331,6 +352,7 @@ + @@ -403,6 +425,7 @@ + @@ -468,6 +491,10 @@ + + + + @@ -492,7 +519,11 @@ + + + + @@ -505,6 +536,10 @@ + + + + @@ -638,4 +673,4 @@ - \ No newline at end of file + diff --git a/PowerEditor/installer/nativeLang/german.xml b/PowerEditor/installer/nativeLang/german.xml index 9df6c3f2..46196f38 100644 --- a/PowerEditor/installer/nativeLang/german.xml +++ b/PowerEditor/installer/nativeLang/german.xml @@ -1,8 +1,8 @@ - + - + + diff --git a/PowerEditor/installer/nativeLang/hungarian.xml b/PowerEditor/installer/nativeLang/hungarian.xml index 8691d467..75979e8c 100644 --- a/PowerEditor/installer/nativeLang/hungarian.xml +++ b/PowerEditor/installer/nativeLang/hungarian.xml @@ -3,9 +3,9 @@ - + - +
@@ -303,6 +303,7 @@ +
@@ -339,7 +340,7 @@ - + diff --git a/PowerEditor/installer/nativeLang/russian.xml b/PowerEditor/installer/nativeLang/russian.xml index 98ef701b..cff88663 100644 --- a/PowerEditor/installer/nativeLang/russian.xml +++ b/PowerEditor/installer/nativeLang/russian.xml @@ -84,6 +84,7 @@ + @@ -244,11 +245,11 @@ - - - - - + + + + + @@ -740,11 +741,11 @@ - - - - - + + + + + @@ -756,7 +757,7 @@ - + diff --git a/PowerEditor/installer/nativeLang/spanish.xml b/PowerEditor/installer/nativeLang/spanish.xml index 56ae5ed6..2282d0c5 100644 --- a/PowerEditor/installer/nativeLang/spanish.xml +++ b/PowerEditor/installer/nativeLang/spanish.xml @@ -1,6 +1,6 @@ - +
@@ -85,7 +85,8 @@ - + + @@ -351,7 +352,7 @@ - + diff --git a/PowerEditor/installer/nativeLang/tatar.xml b/PowerEditor/installer/nativeLang/tatar.xml new file mode 100644 index 00000000..c08a3dd5 --- /dev/null +++ b/PowerEditor/installer/nativeLang/tatar.xml @@ -0,0 +1,922 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/PowerEditor/installer/nativeLang/turkish.xml b/PowerEditor/installer/nativeLang/turkish.xml index 6f5fa7a5..3e2b9122 100644 --- a/PowerEditor/installer/nativeLang/turkish.xml +++ b/PowerEditor/installer/nativeLang/turkish.xml @@ -1,6 +1,6 @@ - +
@@ -86,6 +86,7 @@ + diff --git a/PowerEditor/installer/nppSetup.nsi b/PowerEditor/installer/nppSetup.nsi index 2f325ebb..69e68b6a 100644 --- a/PowerEditor/installer/nppSetup.nsi +++ b/PowerEditor/installer/nppSetup.nsi @@ -36,10 +36,10 @@ ; Define the application name !define APPNAME "Notepad++" -!define APPVERSION "6.7.8.2" +!define APPVERSION "6.7.9" !define APPNAMEANDVERSION "${APPNAME} v${APPVERSION}" !define VERSION_MAJOR 6 -!define VERSION_MINOR 782 +!define VERSION_MINOR 79 !define APPWEBSITE "http://notepad-plus-plus.org/" @@ -1071,6 +1071,9 @@ SectionGroup "Localization" localization ${MementoUnselectedSection} "Tamil" tamil CopyFiles "$TEMP\nppLocalization\tamil.xml" "$INSTDIR\localization\tamil.xml" ${MementoSectionEnd} + ${MementoUnselectedSection} "Tatar" tatar + CopyFiles "$TEMP\nppLocalization\tatar.xml" "$INSTDIR\localization\tatar.xml" + ${MementoSectionEnd} ${MementoUnselectedSection} "Telugu" telugu CopyFiles "$TEMP\nppLocalization\telugu.xml" "$INSTDIR\localization\telugu.xml" ${MementoSectionEnd} @@ -1791,6 +1794,9 @@ SectionGroup un.localization Section un.tamil Delete "$INSTDIR\localization\tamil.xml" SectionEnd + Section un.tatar + Delete "$INSTDIR\localization\tatar.xml" + SectionEnd Section un.telugu Delete "$INSTDIR\localization\telugu.xml" SectionEnd diff --git a/PowerEditor/installer/packageAll.bat b/PowerEditor/installer/packageAll.bat index 8d597632..5360a417 100644 --- a/PowerEditor/installer/packageAll.bat +++ b/PowerEditor/installer/packageAll.bat @@ -143,7 +143,7 @@ If ErrorLevel 1 PAUSE If ErrorLevel 1 PAUSE "C:\Program Files\7-Zip\7z.exe" a -r .\build\npp.bin.7z .\zipped.package.release\* If ErrorLevel 1 PAUSE -"C:\Program Files\NSIS\Unicode\makensis.exe" nppSetup.nsi +"C:\Program Files (x86)\NSIS\Unicode\makensis.exe" nppSetup.nsi @echo off diff --git a/PowerEditor/src/MISC/Common/LongRunningOperation.cpp b/PowerEditor/src/MISC/Common/LongRunningOperation.cpp index 7191197d..38c34597 100644 --- a/PowerEditor/src/MISC/Common/LongRunningOperation.cpp +++ b/PowerEditor/src/MISC/Common/LongRunningOperation.cpp @@ -25,18 +25,24 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - #include "LongRunningOperation.h" -#include +#include "mutex.h" + +using namespace Yuni; + + -static std::recursive_mutex _operationMutex; LongRunningOperation::LongRunningOperation() { - _operationMutex.lock(); + Mutex::ClassLevelLockable::mutex.lock(); } + LongRunningOperation::~LongRunningOperation() { - _operationMutex.unlock(); -} \ No newline at end of file + Mutex::ClassLevelLockable::mutex.unlock(); +} + + + diff --git a/PowerEditor/src/MISC/Common/mutex.cpp b/PowerEditor/src/MISC/Common/mutex.cpp new file mode 100644 index 00000000..69e72366 --- /dev/null +++ b/PowerEditor/src/MISC/Common/mutex.cpp @@ -0,0 +1,181 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. +// +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#include "mutex.h" +#include +#include +#include + +#if YUNI_ATOMIC_MUST_USE_MUTEX != 0 +#warning Atomic types must ue mutex. the implementation should be checked YUNI_OS_GCC_VERSION +#endif + + + +namespace Yuni +{ + + enum // anonymous + { + /*! + ** \brief The spin count for the critical section object + ** + ** On single-processor systems, the spin count is ignored and the critical section + ** spin count is set to 0 (zero). On multiprocessor systems, if the critical section + ** is unavailable, the calling thread spinsdwSpinCount times before performing a + ** wait operation on a semaphore associated with the critical section. If the critical + ** section becomes free during the spin operation, the calling thread avoids the + ** wait operation. + ** \see http://msdn.microsoft.com/en-us/library/ms683476%28v=vs.85%29.aspx + */ + spinCount = 3000, + }; + + + + inline void Mutex::destroy() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + DeleteCriticalSection(&pSection); + # else + switch (::pthread_mutex_destroy(&pLock)) + { + case 0: // Ok good + { + break; + } + // If an error happens, we will let the program continue but + // it can becaome ugly around here... + case EBUSY: + { + std::cerr << "\nattempt to destroy a mutex while it is locked or referenced\n"; + assert(false and "attempt to destroy a mutex while it is locked or referenced"); + break; + } + default: + { + std::cerr << "\nfailed to destroy a mutex\n"; + assert(false and "\nfailed to destroy a mutex\n"); + break; + } + } + ::pthread_mutexattr_destroy(&pAttr); + # endif + # endif // no thread safe + } + + + inline void Mutex::copy(const Mutex& rhs) + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + InitializeCriticalSectionAndSpinCount(&pSection, spinCount); + (void) rhs; // unused + # else + ::pthread_mutexattr_init(&pAttr); + int type; // = PTHREAD_MUTEX_NORMAL; + if (0 == ::pthread_mutexattr_gettype(&rhs.pAttr, &type)) + { + if (PTHREAD_MUTEX_RECURSIVE == type) + { + # if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN) + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE); + # else + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP); + # endif + } + } + ::pthread_mutex_init(& pLock, &pAttr); + # endif + # else + (void) rhs; // unused + # endif // no thread safe + } + + + + Mutex::Mutex(const Mutex& rhs) + { + copy(rhs); + } + + + Mutex::~Mutex() + { + destroy(); + } + + + Mutex::Mutex(bool recursive) + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + (void) recursive; // already recursive on Windows + InitializeCriticalSectionAndSpinCount(&pSection, spinCount); + # else + ::pthread_mutexattr_init(&pAttr); + if (recursive) + { + # if defined(YUNI_OS_DARWIN) or defined(YUNI_OS_FREEBSD) or defined(YUNI_OS_SOLARIS) or defined(YUNI_OS_SUNOS) or defined(YUNI_OS_HAIKU) or defined(YUNI_OS_CYGWIN) + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE); + # else + ::pthread_mutexattr_settype(&pAttr, PTHREAD_MUTEX_RECURSIVE_NP); + # endif + } + ::pthread_mutex_init(&pLock, &pAttr); + # endif + # else + (void) recursive; + # endif + } + + + Mutex& Mutex::operator = (const Mutex& rhs) + { + // We will recreate the mutex + destroy(); + copy(rhs); + return *this; + } + + + + + +} // namespace Yuni diff --git a/PowerEditor/src/MISC/Common/mutex.h b/PowerEditor/src/MISC/Common/mutex.h new file mode 100644 index 00000000..44a5c15c --- /dev/null +++ b/PowerEditor/src/MISC/Common/mutex.h @@ -0,0 +1,234 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. +// +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#pragma once +#define YUNI_OS_WINDOWS +#define YUNI_HAS_CPP_MOVE +#define YUNI_DECL + +#include + + + +namespace Yuni +{ + + /*! + ** \brief Mechanism to avoid the simultaneous use of a common resource + ** + ** \ingroup Threads + */ + class YUNI_DECL Mutex final + { + public: + /*! + ** \brief A class-level locking mechanism + ** + ** A class-level locking operation locks all objects in a given class during that operation + */ + template + class ClassLevelLockable + { + public: + //! A dedicated mutex for the class T + static Mutex mutex; + + }; // class ClassLevelLockable + + + public: + //! \name Constructor & Destructor + //@{ + /*! + ** \brief Default constructor + ** + ** Recursive by default to keep homogeneous behavior between + ** platforms. + */ + explicit Mutex(bool recursive = true); + /*! + ** \brief Copy constructor + ** + ** This constructor does actually nothing but it allows the compilation + ** of other classes which would implement a copy constructor + */ + Mutex(const Mutex&); + + # ifdef YUNI_HAS_CPP_MOVE + // an OS's native mutex must have invariant address and thus can not be moved + Mutex(Mutex&&) = delete; + #endif + + /*! + ** \brief Destructor + */ + ~Mutex(); + //@} + + //! \name Lock & Unlock + //@{ + /*! + ** \brief Lock the mutex + */ + void lock(); + + /*! + ** \brief Try to lock the mutex + ** + ** \return True if the mutex has been locked, false otherwise + */ + bool trylock(); + + /*! + ** \brief Release the lock + */ + void unlock(); + //@} + + # ifndef YUNI_NO_THREAD_SAFE + # ifndef YUNI_OS_WINDOWS + //! \name Native + //@{ + //! Get the original PThread mutex + ::pthread_mutex_t& pthreadMutex(); + //! Get the original PThread mutex (const) + const ::pthread_mutex_t& pthreadMutex() const; + //@} + # endif + # endif + + + //! \name Operators + //@{ + //! Operator = (do nothing) + Mutex& operator = (const Mutex&); + # ifdef YUNI_HAS_CPP_MOVE + // an OS's native mutex must have invariant address and thus can not be moved + Mutex& operator = (Mutex&&) = delete; + #endif + //@} + + + private: + //! Destroy the current mutex + inline void destroy(); + //! Create the mutex with settings from another mutex + inline void copy(const Mutex& rhs); + + private: + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + //! The critical section + CRITICAL_SECTION pSection; + # else + //! The PThread mutex + ::pthread_mutex_t pLock; + ::pthread_mutexattr_t pAttr; + # endif + # endif + + }; // class Mutex + + + + + /*! + ** \brief Locks a mutex in the constructor and unlocks it in the destructor (RAII). + ** + ** This class is especially usefull for `get` accessor` and/or returned values + ** which have to be thread-safe. + ** This is a very common C++ idiom, known as "Resource Acquisition Is Initialization" (RAII). + ** + ** \code + ** class Foo + ** { + ** public: + ** Foo() : pValue(42) {} + ** ~Foo() {} + ** int getValue() + ** { + ** MutexLocker locker(pMutex); + ** return pValue; + ** } + ** void setValue(const int i) + ** { + ** pMutex.lock(); + ** pValue = i; + ** pMutex.unlock(); + ** } + ** private: + ** int pValue; + ** Mutex pMutex; + ** }; + ** \endcode + */ + class MutexLocker final + { + public: + //! \name Constructor & Destructor + //@{ + /*! + ** \brief Constructor + ** + ** \param m The mutex to lock + */ + MutexLocker(Mutex& m); + //! Destructor + ~MutexLocker(); + //@} + + MutexLocker& operator = (const MutexLocker&) = delete; + + private: + //! Reference to the real mutex + Mutex& pMutex; + + }; // MutexLocker + + + + + //! All mutexes for each class + template Mutex Mutex::ClassLevelLockable::mutex; + + + + +} // namespace Yuni + +# include "mutex.hxx" diff --git a/PowerEditor/src/MISC/Common/mutex.hxx b/PowerEditor/src/MISC/Common/mutex.hxx new file mode 100644 index 00000000..2d0c3810 --- /dev/null +++ b/PowerEditor/src/MISC/Common/mutex.hxx @@ -0,0 +1,116 @@ +// YUNI's default license is the GNU Lesser Public License (LGPL), with some +// exclusions (see below). This basically means that you can get the full source +// code for nothing, so long as you adhere to a few rules. + +// Under the LGPL you may use YUNI for any purpose you wish, and modify it if you +// require, as long as you: +// +// Pass on the (modified) YUNI source code with your software, with original +// copyrights intact : +// * If you distribute electronically, the source can be a separate download +// (either from your own site if you modified YUNI, or to the official YUNI +// website if you used an unmodified version) – just include a link in your +// documentation +// * If you distribute physical media, the YUNI source that you used to build +// your application should be included on that media +// Make it clear where you have customised it. +// +// In addition to the LGPL license text, the following exceptions / clarifications +// to the LGPL conditions apply to YUNI: +// +// * Making modifications to YUNI configuration files, build scripts and +// configuration headers such as yuni/platform.h in order to create a +// customised build setup of YUNI with the otherwise unmodified source code, +// does not constitute a derived work +// * Building against YUNI headers which have inlined code does not constitute a +// derived work +// * Code which subclasses YUNI classes outside of the YUNI libraries does not +// form a derived work +// * Statically linking the YUNI libraries into a user application does not make +// the user application a derived work. +// * Using source code obsfucation on the YUNI source code when distributing it +// is not permitted. +// As per the terms of the LGPL, a "derived work" is one for which you have to +// distribute source code for, so when the clauses above define something as not +// a derived work, it means you don't have to distribute source code for it. +// However, the original YUNI source code with all modifications must always be +// made available. + +#pragma once +#include "mutex.h" + + + +namespace Yuni +{ + + inline void Mutex::lock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + EnterCriticalSection(&pSection); + # else + ::pthread_mutex_lock(&pLock); + # endif + # endif + } + + + inline bool Mutex::trylock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + return (0 != TryEnterCriticalSection(&pSection)); + # else + return (0 == ::pthread_mutex_trylock(&pLock)); + # endif + # else + return false; + # endif + } + + + inline void Mutex::unlock() + { + # ifndef YUNI_NO_THREAD_SAFE + # ifdef YUNI_OS_WINDOWS + LeaveCriticalSection(&pSection); + # else + ::pthread_mutex_unlock(&pLock); + # endif + # endif + } + + + # ifndef YUNI_NO_THREAD_SAFE + # ifndef YUNI_OS_WINDOWS + inline pthread_mutex_t& Mutex::pthreadMutex() + { + return pLock; + } + + inline const pthread_mutex_t& Mutex::pthreadMutex() const + { + return pLock; + } + # endif + # endif + + + + inline MutexLocker::MutexLocker(Mutex& m) : + pMutex(m) + { + m.lock(); + } + + + inline MutexLocker::~MutexLocker() + { + pMutex.unlock(); + } + + + + +} // namespace Yuni diff --git a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h index 39c5d75c..1421a374 100644 --- a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h +++ b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h @@ -46,7 +46,7 @@ enum winVer{WV_UNKNOWN, WV_WIN32S, WV_95, WV_98, WV_ME, WV_NT, WV_W2K, WV_XP, WV -//Here you can find how to use these messages : http://notepad-plus.sourceforge.net/uk/plugins-HOWTO.php +//Here you can find how to use these messages : http://docs.notepad-plus-plus.org/index.php/Messages_And_Notifications #define NPPMSG (WM_USER + 1000) #define NPPM_GETCURRENTSCINTILLA (NPPMSG + 4) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index a9484bb7..ef5d83a5 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -667,7 +667,7 @@ LRESULT Notepad_plus::init(HWND hwnd) _toolBar.setCheck(IDM_LANG_USER_DLG, uddShow); // - // Initialize the default forground & background color + // Initialize the default foreground & background color // StyleArray & globalStyles = (NppParameters::getInstance())->getGlobalStylers(); int i = globalStyles.getStylerIndexByID(STYLE_DEFAULT); @@ -814,7 +814,7 @@ void Notepad_plus::saveDockingParams() nppGUI._dockingData._topHeight = _dockingManager.getDockedContSize(CONT_TOP); nppGUI._dockingData._bottomHight = _dockingManager.getDockedContSize(CONT_BOTTOM); - // clear the conatainer tab information (active tab) + // clear the container tab information (active tab) nppGUI._dockingData._containerTabInfo.clear(); // create a vector to save the current information @@ -926,7 +926,7 @@ int Notepad_plus::getHtmlXmlEncoding(const TCHAR *fileName) const if ((langT != L_XML) && (langT != L_HTML)) return -1; - // Get the begining of file data + // Get the beginning of file data FILE *f = generic_fopen(fileName, TEXT("rb")); if (!f) return -1; @@ -2240,7 +2240,7 @@ void Notepad_plus::addHotSpot() _pEditView->execute(SCI_STARTSTYLING, start, 0xFF); _pEditView->execute(SCI_SETSTYLING, foundTextLen, fs); } - else // generize a new style and add it into a array + else // generalize a new style and add it into a array { style_hotspot = idStyle | mask; // set "hotspot bit" hotspotPairs.push_back(style_hotspot); @@ -2927,7 +2927,7 @@ size_t Notepad_plus::getCurrentDocCharCount(UniMode u) size_t result = 0; size_t endpos = _pEditView->execute(SCI_GETLENGTH); - unsigned char* buf = (unsigned char*)_pEditView->execute(SCI_GETCHARACTERPOINTER); // Scintilla doc sais the pointer can be invalidated by any other "execute" + unsigned char* buf = (unsigned char*)_pEditView->execute(SCI_GETCHARACTERPOINTER); // Scintilla doc said the pointer can be invalidated by any other "execute" #ifdef _OPENMP // parallel counting of characters with OpenMP if(endpos > 50000) // starting threads takes time; for small files it is better to simply count in one thread @@ -3442,8 +3442,6 @@ void Notepad_plus::docGotoAnotherEditView(FileTransferMode mode) bool Notepad_plus::activateBuffer(BufferID id, int whichOne) { - //scnN.nmhdr.code = NPPN_DOCSWITCHINGOFF; //superseeded by NPPN_BUFFERACTIVATED - bool isSnapshotMode = NppParameters::getInstance()->getNppGUI().isSnapshotMode(); if (isSnapshotMode) { diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index a484f190..a5a9967f 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -846,7 +846,8 @@ BEGIN MENUITEM "Notepad++ Home", IDM_HOMESWEETHOME MENUITEM "Notepad++ Project Page", IDM_PROJECTPAGE //MENUITEM "Online Documentation", IDM_ONLINEHELP - MENUITEM "Forum", IDM_FORUM + //MENUITEM "Forum", IDM_FORUM + MENUITEM "Live Support", IDM_ONLINESUPPORT MENUITEM "Get More Plugins", IDM_PLUGINSHOME MENUITEM SEPARATOR MENUITEM "Update Notepad++", IDM_UPDATE_NPP diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 778e0b01..36df2a6a 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -2149,7 +2149,7 @@ void Notepad_plus::command(int id) generic_string warning, title; _nativeLangSpeaker.messageBox("ContextMenuXmlEditWarning", _pPublicInterface->getHSelf(), - TEXT("Editing contextMenu.xml allows you to modify your Notepad++ popup context menu.\rYou have to restart your Notepad++ to take effect after modifying contextMenu.xml."), + TEXT("Editing contextMenu.xml allows you to modify your Notepad++ popup context menu on edit zone.\rYou have to restart your Notepad++ to take effect after modifying contextMenu.xml."), TEXT("Editing contextMenu"), MB_OK|MB_APPLMODAL); } @@ -2296,10 +2296,16 @@ void Notepad_plus::command(int id) ::MessageBox(NULL, COMMAND_ARG_HELP, TEXT("Notepad++ Command Argument Help"), MB_OK); break; } - + /* case IDM_FORUM: { - ::ShellExecute(NULL, TEXT("open"), TEXT("http://sourceforge.net/forum/?group_id=95717"), NULL, NULL, SW_SHOWNORMAL); + ::ShellExecute(NULL, TEXT("open"), TEXT(""), NULL, NULL, SW_SHOWNORMAL); + break; + } + */ + case IDM_ONLINESUPPORT: + { + ::ShellExecute(NULL, TEXT("open"), TEXT("https://gitter.im/notepad-plus-plus/notepad-plus-plus"), NULL, NULL, SW_SHOWNORMAL); break; } diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 7802c2d2..79b914a2 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -1832,6 +1832,91 @@ bool NppParameters::reloadContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plug return getContextMenuFromXmlTree(mainMenuHadle, pluginsMenu); } +int NppParameters::getCmdIdFromMenuEntryItemName(HMENU mainMenuHadle, generic_string menuEntryName, generic_string menuItemName) +{ + int nbMenuEntry = ::GetMenuItemCount(mainMenuHadle); + for (int i = 0; i < nbMenuEntry; ++i) + { + TCHAR menuEntryString[64]; + ::GetMenuString(mainMenuHadle, i, menuEntryString, 64, MF_BYPOSITION); + if (generic_stricmp(menuEntryName.c_str(), purgeMenuItemString(menuEntryString).c_str()) == 0) + { + vector< pair > parentMenuPos; + HMENU topMenu = ::GetSubMenu(mainMenuHadle, i); + int maxTopMenuPos = ::GetMenuItemCount(topMenu); + HMENU currMenu = topMenu; + int currMaxMenuPos = maxTopMenuPos; + + int currMenuPos = 0; + bool notFound = false; + + do { + if (::GetSubMenu(currMenu, currMenuPos)) + { + // Go into sub menu + parentMenuPos.push_back(::make_pair(currMenu, currMenuPos)); + currMenu = ::GetSubMenu(currMenu, currMenuPos); + currMenuPos = 0; + currMaxMenuPos = ::GetMenuItemCount(currMenu); + } + else + { + // Check current menu position. + TCHAR cmdStr[256]; + ::GetMenuString(currMenu, currMenuPos, cmdStr, 256, MF_BYPOSITION); + if (generic_stricmp(menuItemName.c_str(), purgeMenuItemString(cmdStr).c_str()) == 0) + { + return ::GetMenuItemID(currMenu, currMenuPos); + } + + if ((currMenuPos >= currMaxMenuPos) && (parentMenuPos.size() > 0)) + { + currMenu = parentMenuPos.back().first; + currMenuPos = parentMenuPos.back().second; + parentMenuPos.pop_back(); + currMaxMenuPos = ::GetMenuItemCount(currMenu); + } + + if ((currMenu == topMenu) && (currMenuPos >= maxTopMenuPos)) + { + notFound = true; + } + else + { + ++currMenuPos; + } + } + } while (!notFound); + } + } + return -1; +} + +int NppParameters::getPluginCmdIdFromMenuEntryItemName(HMENU pluginsMenu, generic_string pluginName, generic_string pluginCmdName) +{ + int nbPlugins = ::GetMenuItemCount(pluginsMenu); + for (int i = 0; i < nbPlugins; ++i) + { + TCHAR menuItemString[256]; + ::GetMenuString(pluginsMenu, i, menuItemString, 256, MF_BYPOSITION); + if (generic_stricmp(pluginName.c_str(), purgeMenuItemString(menuItemString).c_str()) == 0) + { + HMENU pluginMenu = ::GetSubMenu(pluginsMenu, i); + int nbPluginCmd = ::GetMenuItemCount(pluginMenu); + for (int j = 0; j < nbPluginCmd; ++j) + { + TCHAR pluginCmdStr[256]; + ::GetMenuString(pluginMenu, j, pluginCmdStr, 256, MF_BYPOSITION); + if (generic_stricmp(pluginCmdName.c_str(), purgeMenuItemString(pluginCmdStr).c_str()) == 0) + { + return ::GetMenuItemID(pluginMenu, j); + } + } + } + } + return -1; +} + bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU pluginsMenu) { if (!_pXmlContextMenuDocA) @@ -1875,59 +1960,9 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plugins if (menuEntryName != TEXT("") && menuItemName != TEXT("")) { - int nbMenuEntry = ::GetMenuItemCount(mainMenuHadle); - for (int i = 0 ; i < nbMenuEntry ; ++i) - { - TCHAR menuEntryString[64]; - ::GetMenuString(mainMenuHadle, i, menuEntryString, 64, MF_BYPOSITION); - if (generic_stricmp(menuEntryName.c_str(), purgeMenuItemString(menuEntryString).c_str()) == 0) - { - vector< pair > parentMenuPos; - HMENU topMenu = ::GetSubMenu(mainMenuHadle, i); - int maxTopMenuPos = ::GetMenuItemCount(topMenu); - HMENU currMenu = topMenu; - int currMaxMenuPos = maxTopMenuPos; - - int currMenuPos = 0; - bool notFound = false; - - do { - if ( ::GetSubMenu( currMenu, currMenuPos ) ) { - // Go into sub menu - parentMenuPos.push_back( ::make_pair( currMenu, currMenuPos ) ); - currMenu = ::GetSubMenu( currMenu, currMenuPos ); - currMenuPos = 0; - currMaxMenuPos = ::GetMenuItemCount(currMenu); - } - else { - // Check current menu position. - TCHAR cmdStr[256]; - ::GetMenuString(currMenu, currMenuPos, cmdStr, 256, MF_BYPOSITION); - if (generic_stricmp(menuItemName.c_str(), purgeMenuItemString(cmdStr).c_str()) == 0) - { - int cmdId = ::GetMenuItemID(currMenu, currMenuPos); - _contextMenuItems.push_back(MenuItemUnit(cmdId, displayAs.c_str(), folderName.c_str())); - break; - } - - if ( ( currMenuPos >= currMaxMenuPos ) && ( parentMenuPos.size() > 0 ) ) { - currMenu = parentMenuPos.back().first; - currMenuPos = parentMenuPos.back().second; - parentMenuPos.pop_back(); - currMaxMenuPos = ::GetMenuItemCount( currMenu ); - } - - if ( ( currMenu == topMenu ) && ( currMenuPos >= maxTopMenuPos ) ) { - notFound = true; - } - else { - ++currMenuPos; - } - } - } while (! notFound ); - break; - } - } + int cmd = getCmdIdFromMenuEntryItemName(mainMenuHadle, menuEntryName, menuItemName); + if (cmd != -1) + _contextMenuItems.push_back(MenuItemUnit(cmd, displayAs.c_str(), folderName.c_str())); } else { @@ -1942,29 +1977,9 @@ bool NppParameters::getContextMenuFromXmlTree(HMENU mainMenuHadle, HMENU plugins // if plugin menu existing plls the value of PluginEntryName and PluginCommandItemName are valid if (pluginsMenu && pluginName != TEXT("") && pluginCmdName != TEXT("")) { - int nbPlugins = ::GetMenuItemCount(pluginsMenu); - for (int i = 0 ; i < nbPlugins ; ++i) - { - TCHAR menuItemString[256]; - ::GetMenuString(pluginsMenu, i, menuItemString, 256, MF_BYPOSITION); - if (generic_stricmp(pluginName.c_str(), purgeMenuItemString(menuItemString).c_str()) == 0) - { - HMENU pluginMenu = ::GetSubMenu(pluginsMenu, i); - int nbPluginCmd = ::GetMenuItemCount(pluginMenu); - for (int j = 0 ; j < nbPluginCmd ; ++j) - { - TCHAR pluginCmdStr[256]; - ::GetMenuString(pluginMenu, j, pluginCmdStr, 256, MF_BYPOSITION); - if (generic_stricmp(pluginCmdName.c_str(), purgeMenuItemString(pluginCmdStr).c_str()) == 0) - { - int pluginCmdId = ::GetMenuItemID(pluginMenu, j); - _contextMenuItems.push_back(MenuItemUnit(pluginCmdId, displayAs.c_str(), folderName.c_str())); - break; - } - } - break; - } - } + int pluginCmdId = getPluginCmdIdFromMenuEntryItemName(pluginsMenu, pluginName, pluginCmdName); + if (pluginCmdId != -1) + _contextMenuItems.push_back(MenuItemUnit(pluginCmdId, displayAs.c_str(), folderName.c_str())); } } } diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 63d9bc19..0fe24000 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -1694,6 +1694,8 @@ private: void writePrintSetting(TiXmlElement *element); void initMenuKeys(); //initialise menu keys and scintilla keys. Other keys are initialized on their own void initScintillaKeys(); //these functions have to be called first before any modifications are loaded + int getCmdIdFromMenuEntryItemName(HMENU mainMenuHadle, generic_string menuEntryName, generic_string menuItemName); // return -1 if not found + int getPluginCmdIdFromMenuEntryItemName(HMENU pluginsMenu, generic_string pluginName, generic_string pluginCmdName); // return -1 if not found }; #endif //PARAMETERS_H diff --git a/PowerEditor/src/config.model.xml b/PowerEditor/src/config.model.xml index 26404053..7c08df6c 100644 --- a/PowerEditor/src/config.model.xml +++ b/PowerEditor/src/config.model.xml @@ -46,7 +46,7 @@ 2 : B & W 3 : WYSIWYG but without background colour --> - + - + + diff --git a/PowerEditor/src/localizationString.h b/PowerEditor/src/localizationString.h index 0460f783..3186458c 100644 Binary files a/PowerEditor/src/localizationString.h and b/PowerEditor/src/localizationString.h differ diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 125fcb7b..533a0188 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -485,6 +485,7 @@ #define IDM_HELP (IDM_ABOUT + 8) #define IDM_CONFUPDATERPROXY (IDM_ABOUT + 9) #define IDM_CMDLINEARGUMENTS (IDM_ABOUT + 10) + #define IDM_ONLINESUPPORT (IDM_ABOUT + 11) #define IDM_SETTING (IDM + 8000) diff --git a/PowerEditor/src/resource.h b/PowerEditor/src/resource.h index a5421074..978b1fb8 100644 --- a/PowerEditor/src/resource.h +++ b/PowerEditor/src/resource.h @@ -29,12 +29,12 @@ #ifndef RESOURCE_H #define RESOURCE_H -#define NOTEPAD_PLUS_VERSION TEXT("Notepad++ v6.7.8.2") +#define NOTEPAD_PLUS_VERSION TEXT("Notepad++ v6.7.9") // should be X.Y : ie. if VERSION_DIGITALVALUE == 4, 7, 1, 0 , then X = 4, Y = 71 // ex : #define VERSION_VALUE TEXT("5.63\0") -#define VERSION_VALUE TEXT("6.782\0") -#define VERSION_DIGITALVALUE 6, 7, 8, 2 +#define VERSION_VALUE TEXT("6.79\0") +#define VERSION_DIGITALVALUE 6, 7, 9, 0 #ifndef IDC_STATIC #define IDC_STATIC -1 diff --git a/PowerEditor/visual.net/notepadPlus.vcxproj b/PowerEditor/visual.net/notepadPlus.vcxproj index fde7afc6..9482577c 100644 --- a/PowerEditor/visual.net/notepadPlus.vcxproj +++ b/PowerEditor/visual.net/notepadPlus.vcxproj @@ -256,6 +256,7 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml + @@ -532,6 +533,8 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml + + diff --git a/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj b/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj index 42b7ea7a..0275d1c9 100644 --- a/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj +++ b/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj @@ -141,6 +141,7 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml + @@ -411,6 +412,8 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml + + diff --git a/README.md b/README.md index ae638a8c..04df12c6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ What is Notepad++ ? =================== + +[![Join the chat at https://gitter.im/notepad-plus-plus/notepad-plus-plus](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/notepad-plus-plus/notepad-plus-plus?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Notepad++ is a free (free as in both "free speech" and "free beer") source code editor and Notepad replacement that supports several programming languages and natural languages. Running in the MS Windows environment, its use is governed by GPL License. diff --git a/scintilla/lexers/LexHTML.cxx b/scintilla/lexers/LexHTML.cxx index 0155cd23..e3333181 100644 --- a/scintilla/lexers/LexHTML.cxx +++ b/scintilla/lexers/LexHTML.cxx @@ -423,6 +423,7 @@ static int StateForScript(script_type scriptLanguage) { switch (scriptLanguage) { case eScriptJS: Result = SCE_HJ_START; + break; case eScriptPython: Result = SCE_HP_START; break;