2011年5月26日木曜日

OpenOffice > Java > Googleの発音サービスを利用

SpreadSheetの選択されたセルの文字列の発音を再生するマクロを以前OpenOfficeBasicで作成したが、中国語の再生はうまくいかなかったので、Javaのマクロで作成した。

Javaマクロの作成手順(大雑把に)。

  1. クラスファイルを作成。呼び出されるメソッドのシグネチャは「public static void method_name(XScriptContext)」。
  2. クラスファイルをコンパイルし、jarに固める。
  3. jarファイルを%USER_HOME%\Application Data\OpenOffice.org\3\user\Scripts\Java\Library1に置く。
  4. jarファイルと同じフォルダにparcel-descriptor.xmlという設定ファイルを置く。
  5. OpenOfficeのメニュー「ツール > マクロ > マクロを実行」でダイアログを開き、作成したマクロを選択して実行。
補足1:外部ライブラリ等を利用する場合は、OpenOfficeのメニュー「ツール > オプション」でダイアログを開き、「OpenOffice.org > Java」にてクラスパスを追加する。
(今回は、音声ファイルの再生に、「MpegAudioSPI1.9.5」(http://www.javazoom.net/mp3spi/mp3spi.html) を利用した)

補足2:デバッグしたい場合は、補足1と同じところでJavaの起動パラメータを指定できるので
「-Xrunjdwp:transport=dt_socket,server=y,address=12345,suspend=n」等を指定して、IDE等からリモートデバッグできる。OpenOfficeがJavaVMを起動させるタイミングは、OpenOfficeのメニュー「ツール > マクロ > マクロを実行」でダイアログを開いたときなので、そのタイミングでIDE等から接続すればよい。

参考にしたサイト

-- A.java --
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.script.provider.XScriptContext;

public class A {

private static final String URL = "http://translate.google.com/translate_tts?tl=zh-CN&q=";

public static void a(XScriptContext sc) throws IndexOutOfBoundsException,
WrappedTargetException, IOException, JavaLayerException,
InterruptedException {

String word = Util.getSelectedCellValue(sc);

if ("".equals(word)) {
return;
}
play(word);
}

private static void play(String word) throws IOException,
JavaLayerException, InterruptedException {

InputStream in = null;
Player player = null;
try {
URL url = new URL(URL + URLEncoder.encode(word, "UTF-8"));
URLConnection conn = url.openConnection();
conn.setRequestProperty("Accept", "*/*");
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.connect();
in = conn.getInputStream();

player = new Player(in);
player.play();
while (!player.isComplete()) {
Thread.sleep(500);
}

} catch (IOException e) {
throw e;
} catch (JavaLayerException e) {
throw e;
} finally {
if (in != null) {
in.close();
}
if (player != null) {
player.close();
}
}
}
}

-- Util.java -- 
import com.sun.star.frame.XController;
import com.sun.star.frame.XModel;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.script.provider.XScriptContext;
import com.sun.star.table.XCell;
import com.sun.star.table.XCellRange;
import com.sun.star.text.XText;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.view.XSelectionSupplier;

public class Util {

static String getSelectedCellValue(XScriptContext sc)
throws IndexOutOfBoundsException, WrappedTargetException {

XModel oDoc = (XModel) sc.getDocument();
XModel xSpreadsheetModel = UnoRuntime
.queryInterface(XModel.class, oDoc);
XController xController = xSpreadsheetModel.getCurrentController();

XSelectionSupplier xSel = (XSelectionSupplier) UnoRuntime
.queryInterface(XSelectionSupplier.class, xController);
Object Selection = xSel.getSelection();

XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime.queryInterface(
XServiceInfo.class, Selection);
String info = xServiceInfo.getImplementationName();

if (info.equals("ScCellRangeObj") || info.equals("ScCellObj")) {
XCellRange xSelectedRange = (XCellRange) UnoRuntime.queryInterface(
XCellRange.class, Selection);
XCell oCell = xSelectedRange.getCellByPosition(0, 0);
XText xCellText = (XText) UnoRuntime.queryInterface(XText.class,
oCell);
return xCellText.getString();
}

return "";
}

}

-- parcel-descriptor.xml --
<?xml version="1.0" encoding="UTF-8"?>
<parcel language="Java" xmlns:parcel="scripting.dtd">
    <script language="Java">
        <locale lang="en">
            <displayname value="pronounce chinese"/>
            <description>
                pronounce chinese. 
            </description>
        </locale>
        <functionname value="A.a"/>
        <logicalname value="A.a"/>
        <languagedepprops>
            <prop name="classpath" value="a.jar"/>
        </languagedepprops>
    </script>
</parcel>

0 件のコメント:

コメントを投稿