UniversalIndentGUI 1.2.0
|
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)¤tEdit); 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 }