PageRenderTime 56ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/SpellCheck/tags/SpellCheckR005/src/main/cswilly/jeditPlugins/spell/SpellCheckPlugin.java

#
Java | 414 lines | 298 code | 71 blank | 45 comment | 51 complexity | d8294112cb4339222e8020935d25e10a MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * $Revision: 12870 $
  3. * $Date: 2008-06-21 19:58:42 +0200 (Sat, 21 Jun 2008) $
  4. * $Author: kerik-sf $
  5. *
  6. * Copyright (C) 2001 C. Scott Willy
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package cswilly.jeditPlugins.spell;
  23. import cswilly.spell.FileSpellChecker;
  24. import cswilly.spell.SpellException;
  25. import cswilly.spell.FutureListDicts;
  26. import org.gjt.sp.jedit.EBPlugin;
  27. import org.gjt.sp.jedit.EBMessage;
  28. import org.gjt.sp.jedit.msg.BufferUpdate;
  29. import org.gjt.sp.jedit.GUIUtilities;
  30. import org.gjt.sp.jedit.jEdit;
  31. import org.gjt.sp.jedit.OperatingSystem;
  32. import org.gjt.sp.jedit.View;
  33. import org.gjt.sp.jedit.Buffer;
  34. import org.gjt.sp.jedit.gui.OptionsDialog;
  35. import org.gjt.sp.jedit.gui.StatusBar;
  36. import org.gjt.sp.jedit.textarea.JEditTextArea;
  37. import org.gjt.sp.util.Log;
  38. import java.io.*;
  39. import java.util.*;
  40. import javax.swing.*;
  41. import java.awt.BorderLayout;
  42. import java.awt.Color;
  43. import java.util.concurrent.Future;
  44. public class SpellCheckPlugin
  45. extends EBPlugin
  46. {
  47. public static final String PLUGIN_NAME = "SpellCheck";
  48. public static final String SPELL_CHECK_ACTIONS = "spell-check-menu";
  49. public static final String ASPELL_EXE_PROP = "spell-check-aspell-exe";
  50. public static final String ASPELL_MARKUP_MODE_PROP = "spell-check-aspell-markup-mode";
  51. public static final String ASPELL_LANG_PROP = "spell-check-aspell-lang";
  52. public static final String ASPELL_OTHER_PARAMS_PROP = "spell-check-aspell-other-params";
  53. public static final String FILTER_AUTO = "AUTO";
  54. public static final String FILTERS_PROP = "spell-check-filter";
  55. public static final String SPELLCHECK_ON_SAVE_PROP = "spell-check-on-save";
  56. public static final String BUFFER_LANGUAGE_PROP = "spell-check-buffer-lang";
  57. public static enum AspellMarkupMode{
  58. NO_MARKUP_MODE("aspellNoMarkupMode"),
  59. MANUAL_MARKUP_MODE("aspellManualMarkupMode"),
  60. AUTO_MARKUP_MODE("aspellAutoMarkupMode");
  61. AspellMarkupMode(String v){ this.value = v; }
  62. private final String value;
  63. public String toString(){ return value; }
  64. public static AspellMarkupMode fromString(String s){
  65. for(AspellMarkupMode mode : AspellMarkupMode.values()){
  66. if(mode.value.equals(s))return mode;
  67. }
  68. throw new IllegalArgumentException("Invalid mode name :"+s);
  69. }
  70. }
  71. public static final ArrayList defaultModes = new ArrayList( Arrays.asList( new String[] {"html", "shtml", "sgml", "xml", "xsl"} ) );
  72. // private static FileSpellChecker _fileSpellChecker = null;
  73. private static BufferSpellChecker _bufferSpellChecker = null;
  74. private static ErrorListSpellChecker _errorListSpellChecker = null;
  75. private static String aspellMainLanguage;
  76. private static List<String> aspellCommandLine;
  77. /**
  78. * Displays the spell checker dialog box with specified lang dictionary. This method
  79. * is called by the spell-check-selection-with-lang action, defined in actions.xml.
  80. */
  81. public static void showCustomLangSpellDialog(View view,Buffer buffer)
  82. throws SpellException
  83. {
  84. String oldDict = buffer.getStringProperty(BUFFER_LANGUAGE_PROP);
  85. setBufferLanguage(view,buffer);
  86. checkBuffer(view,buffer);
  87. buffer.setStringProperty(BUFFER_LANGUAGE_PROP,oldDict);
  88. }
  89. private static String pickLanguage(View view,Buffer buffer)
  90. {
  91. String result = null;
  92. String oldDict = buffer.getStringProperty(BUFFER_LANGUAGE_PROP);
  93. Log.log(Log.DEBUG,SpellCheckPlugin.class,buffer.getName()+" was in "+oldDict);
  94. if(oldDict == null)oldDict = getAspellMainLanguage();
  95. final DictionaryPicker dp = new DictionaryPicker(oldDict);
  96. dp.getPropertyStore().put(ASPELL_EXE_PROP,getAspellExeFilename());
  97. JDialog dialog = dp.asDialog(view);
  98. dp.getRefreshAction().actionPerformed(null);
  99. dialog.setVisible(true);
  100. if(dp.getPropertyStore().get(DictionaryPicker.CONFIRMED_PROP)!=null)
  101. {
  102. Log.log(Log.DEBUG,SpellCheckPlugin.class,"confirmed");
  103. result = dp.getPropertyStore().get(DictionaryPicker.LANG_PROP);
  104. }
  105. else
  106. {
  107. Log.log(Log.DEBUG,SpellCheckPlugin.class,"cancelled");
  108. }
  109. return result;
  110. }
  111. public static
  112. void checkBufferErrorList(View view, Buffer buffer)
  113. {
  114. ErrorListSpellChecker checker = null;
  115. Log.log(Log.DEBUG,SpellCheckPlugin.class,"SpellCheck started for "+buffer.getName()+" ("+buffer.getPath()+")");
  116. StatusBar status = view.getStatus();
  117. status.setMessage( "Spell check in process..." );
  118. initCommandLine(buffer);
  119. try
  120. {
  121. checker = getErrorListSpellChecker();
  122. if ( checker == null )
  123. throw new SpellException("No or invalid executable specified");
  124. //TODO handle return
  125. checker.checkBuffer( buffer );
  126. Log.log(Log.DEBUG,SpellCheckPlugin.class,"SpellCheck finished for "+buffer.getName()+" ("+buffer.getPath()+")");
  127. }
  128. catch( SpellException e )
  129. {
  130. Log.log(Log.ERROR, SpellCheckPlugin.class, "Error spell checking (Aspell).");
  131. Log.log(Log.ERROR, SpellCheckPlugin.class, e);
  132. Object[] args = { new String (e.getMessage()) };
  133. GUIUtilities.error( view, "spell-check-error", args);
  134. }
  135. }
  136. private static void initCommandLine(Buffer buffer){
  137. String dict = buffer.getStringProperty(BUFFER_LANGUAGE_PROP);
  138. if(dict == null) dict = jEdit.getProperty(ASPELL_LANG_PROP,"");
  139. setAspellMainLanguage(dict);
  140. // Construct aspell command line arguments
  141. List aspellCommandLine = new ArrayList(4);
  142. // use this option switch to prevent any encoding issue
  143. // available at least since aspell 0.5.3
  144. aspellCommandLine.add("--encoding=utf-8");
  145. String mode = buffer.getMode().getName();
  146. AspellMarkupMode markup = getAspellMarkupMode();
  147. if( AspellMarkupMode.NO_MARKUP_MODE == markup)
  148. aspellCommandLine.add("--mode=none");
  149. else if( AspellMarkupMode.MANUAL_MARKUP_MODE == markup ){
  150. String m = jEdit.getProperty(FILTERS_PROP+"."+mode);
  151. if(m!=null)
  152. aspellCommandLine.add("--mode="+m);
  153. }
  154. //else : AUTO : do nothing
  155. String aspellMainLanguage = getAspellMainLanguage();
  156. if ( !aspellMainLanguage.equals("") ){
  157. aspellCommandLine.add("--lang=" + aspellMainLanguage);
  158. //can't find this option:
  159. //aspellCommandLine.add("--language-tag=" + aspellMainLanguage);
  160. }
  161. String aspellOtherParams = getAspellOtherParams();
  162. //TODO : fix params with spaces protected with quotes
  163. for(StringTokenizer st=new StringTokenizer(aspellOtherParams);st.hasMoreTokens();){
  164. aspellCommandLine.add(st.nextToken());
  165. }
  166. aspellCommandLine.add("pipe");
  167. setAspellCommandLine( aspellCommandLine);
  168. }
  169. public static
  170. void checkBuffer(View view,Buffer buffer)
  171. {
  172. JEditTextArea area = view.getEditPane().getTextArea();
  173. if(area.getBuffer()!=buffer)
  174. throw new IllegalArgumentException("The buffer must correspond to the first area");
  175. BufferSpellChecker checker = null;
  176. StatusBar status = view.getStatus();
  177. status.setMessage( "Spell check in process..." );
  178. initCommandLine(buffer);
  179. try
  180. {
  181. checker = getBufferSpellChecker();
  182. if ( checker == null )
  183. throw new SpellException("No or invalid executable specified");
  184. //TODO handle return
  185. checker.checkBuffer( area, buffer );
  186. status.setMessage( "Spell terminated with no Error..." );
  187. }
  188. catch( SpellException e )
  189. {
  190. Log.log(Log.ERROR, SpellCheckPlugin.class, "Error spell checking (Aspell).");
  191. Log.log(Log.ERROR, SpellCheckPlugin.class, e);
  192. Object[] args = { new String (e.getMessage()) };
  193. GUIUtilities.error( view, "spell-check-error", args);
  194. }
  195. }
  196. /**
  197. * sets buffer's property SpellCheckPlugin.BUFFER_LANGUAGE_PROP
  198. * according to user's choice
  199. * @param view Currently Active view
  200. * @param buffer Buffer whose language is to be set
  201. */
  202. public static void setBufferLanguage(View view, final Buffer buffer)
  203. {
  204. String oldDict = buffer.getStringProperty(BUFFER_LANGUAGE_PROP);
  205. Log.log(Log.DEBUG,SpellCheckPlugin.class,buffer.getName()+" was in "+oldDict);
  206. String result = pickLanguage(view,buffer);
  207. if(result != null){
  208. Log.log(Log.DEBUG,SpellCheckPlugin.class,buffer.getName()+" is in "+result);
  209. buffer.setStringProperty(BUFFER_LANGUAGE_PROP,result);
  210. }
  211. }
  212. private static
  213. BufferSpellChecker getBufferSpellChecker()
  214. {
  215. String aspellExeFilename = getAspellExeFilename();
  216. String[] aspellCommandLine = (String[])getAspellCommandLine().toArray(new String[]{});
  217. if ( aspellExeFilename == null )
  218. return null;
  219. if( _bufferSpellChecker == null )
  220. _bufferSpellChecker = new BufferSpellChecker( aspellExeFilename, aspellCommandLine );
  221. else
  222. if( !aspellExeFilename.equals( _bufferSpellChecker.getAspellExeFilename() )
  223. || !aspellCommandLine.equals( _bufferSpellChecker.getAspellArgs() ) )
  224. {
  225. _bufferSpellChecker.stop();
  226. _bufferSpellChecker = new BufferSpellChecker( aspellExeFilename, aspellCommandLine );
  227. }
  228. return _bufferSpellChecker;
  229. }
  230. private static
  231. ErrorListSpellChecker getErrorListSpellChecker()
  232. {
  233. String aspellExeFilename = getAspellExeFilename();
  234. String[] aspellCommandLine = (String[])getAspellCommandLine().toArray(new String[]{});
  235. if ( aspellExeFilename == null )
  236. return null;
  237. if( _errorListSpellChecker == null )
  238. _errorListSpellChecker = new ErrorListSpellChecker( aspellExeFilename, aspellCommandLine );
  239. else
  240. if( !aspellExeFilename.equals( _errorListSpellChecker.getAspellExeFilename() )
  241. || !aspellCommandLine.equals( _errorListSpellChecker.getAspellArgs() ) )
  242. {
  243. _errorListSpellChecker.stop();
  244. _errorListSpellChecker = new ErrorListSpellChecker( aspellExeFilename, aspellCommandLine );
  245. }
  246. return _errorListSpellChecker;
  247. }
  248. static
  249. String getAspellExeFilename()
  250. {
  251. String aspellExeFilename = jEdit.getProperty( ASPELL_EXE_PROP );
  252. if( aspellExeFilename == null || aspellExeFilename.equals("") )
  253. {
  254. if ( OperatingSystem.isUnix() )
  255. aspellExeFilename = "aspell";
  256. else
  257. {
  258. GUIUtilities.message(null, "spell-check-noAspellExe", null);
  259. String[] paths = GUIUtilities.showVFSFileDialog( null, null, JFileChooser.OPEN_DIALOG, false );
  260. if (paths != null)
  261. aspellExeFilename = paths[0];
  262. else
  263. {
  264. return null;
  265. }
  266. }
  267. jEdit.setProperty( SpellCheckPlugin.ASPELL_EXE_PROP, aspellExeFilename );
  268. }
  269. return aspellExeFilename;
  270. }
  271. private static
  272. List<String> getAspellCommandLine()
  273. {
  274. if( aspellCommandLine == null )
  275. aspellCommandLine = new ArrayList<String>();
  276. return aspellCommandLine;
  277. }
  278. private static
  279. void setAspellCommandLine(List<String> newCommandLine)
  280. {
  281. aspellCommandLine = newCommandLine;
  282. Log.log(Log.DEBUG,SpellCheckPlugin.class,"setting command line "+newCommandLine);
  283. }
  284. public static
  285. String getAspellMainLanguage()
  286. {
  287. if( aspellMainLanguage == null )
  288. aspellMainLanguage = "";
  289. return aspellMainLanguage;
  290. }
  291. private static
  292. void setAspellMainLanguage(String newLanguage)
  293. {
  294. aspellMainLanguage = newLanguage;
  295. }
  296. private static
  297. String getAspellOtherParams()
  298. {
  299. return jEdit.getProperty( ASPELL_OTHER_PARAMS_PROP, "");
  300. }
  301. private static
  302. AspellMarkupMode getAspellMarkupMode()
  303. {
  304. try{
  305. return AspellMarkupMode.fromString(jEdit.getProperty( ASPELL_MARKUP_MODE_PROP));
  306. }catch(IllegalArgumentException iae){
  307. return AspellMarkupMode.AUTO_MARKUP_MODE;
  308. }
  309. }
  310. public static
  311. Future<Vector<String>> getAlternateLangDictionaries()
  312. {
  313. return new FutureListDicts(getAspellExeFilename());
  314. }
  315. public void stop(){
  316. Log.log(Log.DEBUG,this,"stopping SpellCheckPlugin");
  317. // if(_fileSpellChecker != null){
  318. // _fileSpellChecker.stop();
  319. // _fileSpellChecker = null;
  320. // }
  321. if(_errorListSpellChecker != null){
  322. _errorListSpellChecker.unload();
  323. _errorListSpellChecker = null;
  324. }
  325. if(_bufferSpellChecker!=null){
  326. _bufferSpellChecker.unload();
  327. _bufferSpellChecker = null;
  328. }
  329. }
  330. public void handleMessage(EBMessage message){
  331. if(!jEdit.getBooleanProperty(SPELLCHECK_ON_SAVE_PROP))return;
  332. if(message instanceof BufferUpdate){
  333. final BufferUpdate bu = (BufferUpdate)message;
  334. if(BufferUpdate.SAVED == bu.getWhat()){
  335. new Thread("SpellCheck-"+bu.getBuffer().getName()){
  336. public void run(){
  337. checkBufferErrorList(bu.getView(), bu.getBuffer());
  338. }
  339. }.start();
  340. }
  341. }
  342. }
  343. }