UniversalIndentGUI 1.2.0
UniversalIndentGUI_NPP.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002 *   Copyright (C) 2006-2012 by Thomas Schweitzer                          *
00003 *   thomas-schweitzer(at)arcor.de                                         *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU General Public License version 2.0 as   *
00007 *   published by the Free Software Foundation.                            *
00008 *                                                                         *
00009 *   This program is distributed in the hope that it will be useful,       *
00010 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012 *   GNU General Public License for more details.                          *
00013 *                                                                         *
00014 *   You should have received a copy of the GNU General Public License     *
00015 *   along with this program in the file LICENSE.GPL; if not, write to the *
00016 *   Free Software Foundation, Inc.,                                       *
00017 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00018 ***************************************************************************/
00019 
00020 
00021 /* include files */
00022 #include "UniversalIndentGUI_NPP.h"
00023 
00024 #include "UiGuiLogger.h"
00025 #include "UiGuiSystemInfo.h"
00026 #include "UiGuiVersion.h"
00027 
00028 /* information for notepad */
00029 CONST INT   nbFunc  = 3;
00030 CONST TCHAR  PLUGIN_NAME[] = _T("&UniversalIndentGUI");
00031 
00032 /* global values */
00033 HANDLE              g_hModule           = NULL;
00034 NppData             nppData;
00035 FuncItem            funcItem[nbFunc];
00036 
00037 IndentHandler *indentHandler;
00038 
00039 /* settings */
00040 TCHAR               configPath[MAX_PATH];
00041 TCHAR               iniFilePath[MAX_PATH];
00042 tPluginProp         pluginProp;
00043 
00044 
00045 /* main function of dll */
00046 BOOL APIENTRY DllMain( HANDLE hModule, DWORD reasonForCall, LPVOID lpReserved ) {
00047     g_hModule = hModule;
00048 
00049     switch (reasonForCall)
00050     {
00051         case DLL_PROCESS_ATTACH :
00052         {
00053             if (!qApp) {
00054                 int argc = 1;
00055                 char *argv[] = {"setup", NULL};
00056                 static QApplication qapp(argc, argv);
00057                 indentHandler = new IndentHandler(0);
00058                 indentHandler->setWindowModality( Qt::ApplicationModal );
00059                 indentHandler->setWindowTitle("UniversalIndentGUI");
00060                 indentHandler->setWindowIcon(QIcon(QString::fromUtf8(":/mainWindow/icon2.png")));
00061                 indentHandler->setParameterChangedCallback( NULL );
00062                 indentHandler->setWindowClosedCallback( showUiGUI );
00063 
00064                 // Setting UTF-8 as default 8-Bit encoding to ensure that qDebug does no false string conversion.
00065                 QTextCodec::setCodecForCStrings( QTextCodec::codecForName("UTF-8") );
00066                 QTextCodec::setCodecForLocale( QTextCodec::codecForName("UTF-8") );
00067                 // Force creation of an UiGuiLogger instance here, to avoid recursion with SettingsPaths init function.
00068                 UiGuiLogger::getInstance();
00069                 qInstallMsgHandler( UiGuiLogger::messageHandler );
00070                 UiGuiLogger::messageHandler( UiGuiInfoMsg, QString("Starting UiGUI Version %1 %2").arg(PROGRAM_VERSION_STRING).arg(PROGRAM_REVISION).toAscii() );
00071                 UiGuiLogger::messageHandler( UiGuiInfoMsg, QString("Running on %1").arg(UiGuiSystemInfo::getOperatingSystem()).toAscii() );
00072 
00073 #ifdef _DEBUG
00074                 UiGuiLogger::getInstance()->setVerboseLevel(0);
00075 #endif
00076             }
00077 
00078             /* Set function pointers */
00079             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pFunc = showUiGUI;
00080             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pFunc = indentText;
00081             funcItem[TOGGLE_AUTO_UPDATE_INDEX]._pFunc = toggleAutoUpdate;
00082 
00083             /* Fill menu names */
00084 #ifdef UNICODE
00085             wcscpy(funcItem[TOGGLE_SHOW_UIGUI_INDEX]._itemName, _T("&Show Parameter Settings"));
00086             wcscpy(funcItem[EXECUTE_TEXT_INDENT_INDEX]._itemName, _T("&Indent text"));
00087             wcscpy(funcItem[TOGGLE_AUTO_UPDATE_INDEX]._itemName, _T("&Enable Text Auto Update"));
00088 #else
00089             strcpy(funcItem[TOGGLE_SHOW_UIGUI_INDEX]._itemName, "&Show Parameter Settings");
00090             strcpy(funcItem[EXECUTE_TEXT_INDENT_INDEX]._itemName, "&Indent text");
00091             strcpy(funcItem[TOGGLE_AUTO_UPDATE_INDEX]._itemName, "&Enable Text Auto Update");
00092 #endif
00093 
00094             /* Set shortcuts */
00095             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey = new ShortcutKey;
00096             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey->_isAlt   = true;
00097             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey->_isCtrl  = true;
00098             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey->_isShift = true;
00099             funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey->_key     = 'T';
00100             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pShKey = new ShortcutKey;
00101             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pShKey->_isAlt   = true;
00102             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pShKey->_isCtrl  = true;
00103             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pShKey->_isShift = true;
00104             funcItem[EXECUTE_TEXT_INDENT_INDEX]._pShKey->_key     = 'J';
00105             funcItem[TOGGLE_AUTO_UPDATE_INDEX]._pShKey = NULL;
00106             break;
00107         }
00108         case DLL_PROCESS_DETACH :
00109         {
00110             delete funcItem[TOGGLE_SHOW_UIGUI_INDEX]._pShKey;
00111             delete indentHandler;
00112 
00113             /* save settings */
00114             saveSettings();
00115             break;
00116         }
00117         case DLL_THREAD_ATTACH :
00118             break;
00119 
00120         case DLL_THREAD_DETACH :
00121             break;
00122     }
00123 
00124     return TRUE;
00125 }
00126 
00127 
00128 extern "C" __declspec(dllexport) void setInfo(NppData notpadPlusData) {
00129     /* stores notepad data */
00130     nppData = notpadPlusData;
00131 
00132     /* load data of plugin */
00133     loadSettings();
00134 
00135     /* initial dialogs */
00136     //universalIndentGUI_NPPDialog.init((HINSTANCE)g_hModule, nppData, &pluginProp);
00137 }
00138 
00139 
00140 extern "C" __declspec(dllexport) const TCHAR * getName() {
00141     return PLUGIN_NAME;
00142 }
00143 
00144 
00145 extern "C" __declspec(dllexport) FuncItem * getFuncsArray(INT *nbF)
00146 {
00147     *nbF = nbFunc;
00148     return funcItem;
00149 }
00150 
00151 
00152 #ifdef UNICODE
00153 extern "C" __declspec(dllexport) BOOL isUnicode() {
00154     return true;
00155 }
00156 #endif //UNICODE
00157 
00158 
00159 /***
00160 *   beNotification()
00161 *
00162 *   This function is called, if a notification in Scintilla/Notepad++ occurs
00163 */
00164 extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode) {
00165     if (notifyCode->nmhdr.hwndFrom == nppData._nppHandle) {
00166         /* on this notification code you can register your plugin icon in Notepad++ toolbar */
00167         if (notifyCode->nmhdr.code == NPPN_TBMODIFICATION) {
00168             //g_TBWndMgr.hToolbarBmp = (HBITMAP)::LoadImage((HINSTANCE)g_hModule, MAKEINTRESOURCE(IDB_TOOLBAR), IMAGE_BITMAP, 0, 0, (LR_LOADMAP3DCOLORS));
00169             //::SendMessage(nppData._nppHandle, NPPM_ADDTOOLBARICON, (WPARAM)funcItem[TOGGLE_AUTO_UPDATE_INDEX]._cmdID, (LPARAM)&g_TBWndMgr);
00170         }
00171     }
00172 }
00173 
00174 
00175 /***
00176 *   messageProc()
00177 *
00178 *   This function is called, if a notification from Notepad occurs
00179 */
00180 extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam) {
00181     return TRUE;
00182 }
00183 
00184 
00185 /***
00186 *   loadSettings()
00187 *
00188 *   Load the parameters of plugin
00189 */
00190 void loadSettings(void) {
00191     /* initialize the config directory */
00192     ::SendMessage(nppData._nppHandle, NPPM_GETPLUGINSCONFIGDIR, MAX_PATH, (LPARAM)configPath);
00193 
00194     /* Test if config path exist */
00195     if (PathFileExists(configPath) == FALSE) {
00196         ::CreateDirectory(configPath, NULL);
00197     }
00198 
00199 #ifdef UNICODE
00200     wcscpy(iniFilePath, configPath);
00201     wcscat(iniFilePath, PLUGINTEMP_INI);
00202 #else
00203     strcpy(iniFilePath, configPath);
00204     strcat(iniFilePath, PLUGINTEMP_INI);
00205 #endif
00206 
00207     if (PathFileExists(iniFilePath) == FALSE) {
00208         ::CloseHandle(::CreateFile(iniFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
00209     }
00210 
00211     pluginProp.iValue1  = ::GetPrivateProfileInt(dlgTemp, Value1, 200, iniFilePath);
00212     pluginProp.iValue2  = ::GetPrivateProfileInt(dlgTemp, Value2, 200, iniFilePath);
00213 }
00214 
00215 
00216 /***
00217 *   saveSettings()
00218 *
00219 *   Saves the parameters of plugin
00220 */
00221 void saveSettings(void) {
00222     TCHAR   temp[16];
00223 
00224 #ifdef UNICODE
00225     ::WritePrivateProfileString(dlgTemp, Value1, _itow(pluginProp.iValue1, temp, 10), iniFilePath);
00226     ::WritePrivateProfileString(dlgTemp, Value2, _itow(pluginProp.iValue2, temp, 10), iniFilePath);
00227 #else
00228     ::WritePrivateProfileString(dlgTemp, Value1, _itoa(pluginProp.iValue1, temp, 10), iniFilePath);
00229     ::WritePrivateProfileString(dlgTemp, Value2, _itoa(pluginProp.iValue2, temp, 10), iniFilePath);
00230 #endif
00231 }
00232 
00233 
00234 /**************************************************************************
00235 *   Interface functions
00236 */
00237 void toggleAutoUpdate(void) {
00238     HMENU   hMenu = ::GetMenu(nppData._nppHandle);
00239     UINT state = ::GetMenuState(hMenu, funcItem[TOGGLE_AUTO_UPDATE_INDEX]._cmdID, MF_BYCOMMAND);
00240 
00241     if ( state & MF_CHECKED ) {
00242         indentHandler->setParameterChangedCallback( NULL );
00243         state = ::CheckMenuItem(hMenu, funcItem[TOGGLE_AUTO_UPDATE_INDEX]._cmdID, MF_BYCOMMAND | MF_UNCHECKED);
00244     }
00245     else {
00246         if ( !indentHandler->isVisible() ) {
00247             showUiGUI();
00248         }
00249         indentHandler->setParameterChangedCallback( indentText );
00250         state = ::CheckMenuItem(hMenu, funcItem[TOGGLE_AUTO_UPDATE_INDEX]._cmdID, MF_BYCOMMAND | MF_CHECKED);
00251     }
00252 
00253     indentText();
00254 }
00255 
00256 
00257 void showUiGUI(void) {
00258     HMENU   hMenu = ::GetMenu(nppData._nppHandle);
00259     UINT menuState = ::GetMenuState(hMenu, funcItem[TOGGLE_SHOW_UIGUI_INDEX]._cmdID, MF_BYCOMMAND);
00260     bool windowIsVisible = indentHandler->isVisible();
00261 
00262     if ( menuState & MF_CHECKED ) {
00263         if ( windowIsVisible ) {
00264             indentHandler->hide();
00265         }
00266         menuState = ::CheckMenuItem(hMenu, funcItem[TOGGLE_SHOW_UIGUI_INDEX]._cmdID, MF_BYCOMMAND | MF_UNCHECKED);
00267     }
00268     else {
00269         if ( !windowIsVisible ) {
00270             indentHandler->show();
00271         }
00272         menuState = ::CheckMenuItem(hMenu, funcItem[TOGGLE_SHOW_UIGUI_INDEX]._cmdID, MF_BYCOMMAND | MF_CHECKED);
00273     }
00274 }
00275 
00276 
00277 HWND getCurrentHScintilla(int which) {
00278     return (which == 0) ? nppData._scintillaMainHandle : nppData._scintillaSecondHandle;
00279 };
00280 
00281 
00282 void indentText() {
00283     int currentEdit = 0;
00284     int textLength = 0;
00285     char *fullEditorText = NULL;
00286 
00287     // Get scintilla text edit window handle
00288     //::SendMessage(nppData._nppHandle, WM_GETCURRENTSCINTILLA, 0, (LPARAM)&currentEdit);
00289 
00290     // Get the length of the selected text plus a 0 byte ending.
00291     textLength = ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETSELTEXT, 0, 0);
00292 
00293     // No text has been selected to format the whole text.
00294     if ( textLength - 1 == 0 ) {
00295         textLength = ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETTEXTLENGTH, 0, 0);
00296         // Because we need space for a trailing 0 byte increment the length.
00297         textLength++;
00298 
00299         fullEditorText = new char[textLength];
00300 
00301         // Get whole text.
00302         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETTEXT, textLength, (LPARAM)fullEditorText);
00303 
00304         // Get the first visible line and add the max visible lines to it so later scrolling to the correct position is ensured.
00305         int firstLine = ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETFIRSTVISIBLELINE, 0, 0);
00306         firstLine += ::SendMessage(getCurrentHScintilla(currentEdit), SCI_LINESONSCREEN, 0, 0) - 1;
00307 
00308         QString indentedText = indentHandler->callIndenter(fullEditorText, "cpp");
00309 
00310         QByteArray indentedTextByteArray = indentedText.toAscii();
00311 
00312         // Set whole text.
00313         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_SETTEXT, 0, (LPARAM)indentedTextByteArray.constData());
00314 
00315         // Set first visible line again.
00316         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GOTOLINE, firstLine, 0);
00317     }
00318     // Format only the selected text.
00319     else {
00320         fullEditorText = new char[textLength];
00321 
00322         // Get selection start.
00323         int selectionStartPos = ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETSELECTIONSTART, 0, 0);
00324 
00325         // Get the selected text.
00326         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_GETSELTEXT, 0, (LPARAM)fullEditorText);
00327 
00328         QString indentedText = indentHandler->callIndenter(fullEditorText, "cpp");
00329 
00330         QByteArray indentedTextByteArray = indentedText.toAscii();
00331 
00332         // Replace selected text.
00333         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_REPLACESEL, 0, (LPARAM)indentedTextByteArray.constData());
00334 
00335         // Set selection again.
00336         ::SendMessage(getCurrentHScintilla(currentEdit), SCI_SETSEL, selectionStartPos, selectionStartPos + indentedTextByteArray.length() );
00337     }
00338 
00339     delete [] fullEditorText;
00340     fullEditorText = NULL;
00341 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines