001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.plugin.column;
017
018import org.opengion.hayabusa.db.AbstractEditor;
019import org.opengion.hayabusa.db.CellEditor;
020import org.opengion.hayabusa.db.DBColumn;
021import org.opengion.fukurou.util.XHTMLTag;
022import org.opengion.hayabusa.common.HybsSystem;
023import org.opengion.fukurou.util.Attributes;
024import org.opengion.fukurou.util.StringUtil;
025import org.opengion.fukurou.util.TagBuffer;
026
027/**
028 * OCR2 エディターは、tesseract.js を利用した、カメラ映像で取り込んだvideoを
029 * canvasにキャプチャしてから、文字に変換して テキストエリアに書き出すクラスです。
030 *
031 * 基本的な構造は、カメラ映像描画開始ボタン、静止画キャプチャボタン、映像表示領域(video)、
032 * 静止画描画領域(canvas)、進捗(progressbar)、textarea で構成されます。
033 * 映像表示領域(video)でキャプチャすると、静止画を同じ場所に上書きします。もう一度押すと再度映像に切り替わります。
034 * textarea の name 以外は、固定です。よって、各ページに、1つしか設定できません。
035 *
036 *    <button type='button' id='vidStart' onClick='videoStart()'>Video Start</button>
037 *    <button type='button' id='capStart' onClick='capture()'>Capture</button><br />
038 *    <div id='videotop' style='display:flex;' >
039 *        <video id='player' autoplay style='background-color: black;position: absolute;z-index: 1;'></video>
040 *        <canvas id='snapshot' style='visibility:hidden;z-index: 2; '></canvas>
041 *    </div>
042 *    <progress id='progressbar' min='0' max='1' value='0' > </progress><br />
043 *    <textarea name='outdata' id='outdata' rows='10'cols='80'> </textarea>
044 *
045 * script に CDNサービス を使うと、無線環境(iPad等)ではものすごく遅くなったため、ローカルに配置することにします。
046 * <script src="https://unpkg.com/tesseract.js"><!-- --></script>
047 *
048 * script は、tesseract.min.js を使います。現在、1画面1つしかカメラは使えません。
049 * これらは、使用する画面に、組み込んでください。
050 * <script src="{@SYS.JSP}/option/tesseract.min.js"><!-- --></script>
051 * <script src="{@SYS.JSP}/option/videocamera.js"><!-- --></script>
052 *
053 * を使用するページに設定します。
054 *
055 * @og.rev 7.4.2.1 (2021/05/21) 新規作成
056 * @og.group データ編集
057 *
058 * @version  7.4
059 * @author   Kazuhiko Hasegawa
060 * @since    JDK11.0,
061 */
062public class Editor_OCR2 extends AbstractEditor {
063        /** このプログラムのVERSION文字列を設定します。   {@value} */
064        private static final String VERSION = "7.4.2.1 (2021/05/21)" ;
065
066//      // 7.4.2.2 (2021/05/28) システム定数のJSPを使用します。(※ SYS.JSP + SYS.IMAGE_DIR)
067//      private static final String JSP_OPT =  HybsSystem.sys( "JSP" ) + "/option/" ;
068
069//      private static final String JS_SRC = "<script src='" + JSP_OPT + "tesseract.min.js' ><!-- --></script>"
070//                                                              + CR +   "<script src='" + JSP_OPT + "videocamera.js' ><!-- --></script>" ;
071
072        private static final String BASE_HTML =
073                                                                        "<button type='button' id='vidStart' onClick='videoStart()'>Video Start</button>"
074                                                        + CR +  "<button type='button' id='capStart' onClick='capture()'>Capture</button><br />"
075                                                        + CR +  "<div id='videotop' style='display:flex;' >"
076                                                        + CR +  "  <video id='player' autoplay style='background-color: black;position: absolute;z-index: 1;'></video>"
077                                                        + CR +  "  <canvas id='snapshot' style='visibility:hidden;z-index: 2; '></canvas>"
078                                                        + CR +  "</div>"
079                                                        + CR +  "<progress id='progressbar' min='0' max='1' value='0' > </progress><br />" ;
080
081        /** 列1 */ protected  String     cols1   ;
082        /** 列2 */ protected  String     cols2   ;
083        /** 行1 */ protected  String     rows1   ;
084        /** 行2 */ protected  String     rows2   ;
085
086        /**
087         * デフォルトコンストラクター。
088         * このコンストラクターで、基本オブジェクトを作成します。
089         *
090         * @og.rev 7.4.2.1 (2021/05/21) 新規作成
091         *
092         */
093        public Editor_OCR2() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
094
095        /**
096         * コンストラクター。
097         *
098         * @og.rev 7.4.2.1 (2021/05/21) 新規作成
099         *
100         * @param       clm     DBColumnオブジェクト
101         */
102        protected Editor_OCR2( final DBColumn clm ) {
103                super( clm );
104                final String  disabled = clm.isWritable() ? null : "disabled" ;
105
106                final int r1 = clm.getTotalSize()/Integer.parseInt(size1) + 1;
107                rows1 = String.valueOf( r1 );
108
109                final int r2 = clm.getTotalSize()/Integer.parseInt(size2) + 1;
110                rows2 = String.valueOf( r2 );
111
112                // size に、"rows,cols" を指定できるように変更
113                final String param = StringUtil.nval( clm.getEditorParam(),clm.getViewLength() );
114                if( param != null && param.length() != 0 ) {
115                        final int st = param.indexOf( ',' );
116                        if( st > 0 ) {
117                                rows1 = param.substring( 0,st );
118                                rows2 = rows1 ;
119                                cols1 = param.substring( st+1 );
120                                cols2 = cols1;
121                        }
122                }
123
124                // size1,size2 を使わずに、cols1,cols2 を使用。
125                if( cols1 == null || cols2 == null ) {
126                        cols1   = size1  ;
127                        cols2   = size2  ;
128                }
129
130                // Attributesの連結記述
131                attributes = new Attributes()
132                                        .set( "disabled"        , disabled )
133                                        .set( clm.getEditorAttributes() )                               // #addAttributes( Attributes ) の代替え
134                                        .add( "class"           , clm.getDbType() );
135
136                tagBuffer.add( XHTMLTag.textareaAttri( attributes ) );
137        }
138
139        /**
140         * 各オブジェクトから自分のインスタンスを返します。
141         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
142         * まかされます。
143         *
144         * @og.rev 7.4.2.1 (2021/05/21) 新規作成
145         *
146         * @param       clm     DBColumnオブジェクト
147         *
148         * @return      CellEditorオブジェクト
149         * @og.rtnNotNull
150         */
151        public CellEditor newInstance( final DBColumn clm ) {
152                return new Editor_OCR2( clm );
153        }
154
155        /**
156         * データの編集用文字列を返します。
157         *
158         * @og.rev 7.4.2.1 (2021/05/21) 新規作成
159         *
160         * @param   value 入力値
161         *
162         * @return  データの編集用文字列
163         * @og.rtnNotNull
164         */
165        @Override
166        public String getValue( final String value ) {
167                // TagBufferの連結記述
168                return BASE_HTML
169                                +       new TagBuffer( "textarea" )
170                                                .add( "name"    , name )
171                                                .add( "id"              , "outdata" )                           // ID 固定です。
172                                                .add( "cols"    , cols2 )
173                                                .add( "rows"    , rows2 )
174                                                .add( tagBuffer.makeTag() )
175                                                .addBody( value )
176                                                .makeTag();
177        }
178
179        /**
180         * name属性を変えた、データ表示/編集用のHTML文字列を作成します。
181         * テーブル上の name に 行番号を付加して、名前_行番号 で登録するキーを作成し、
182         * リクエスト情報を1つ毎のフィールドで処理できます。
183         *
184         * @og.rev 7.4.2.1 (2021/05/21) 新規作成
185         *
186         * @param   row   行番号
187         * @param   value 入力値
188         *
189         * @return  データ表示/編集用の文字列
190         * @og.rtnNotNull
191         */
192        @Override
193        public String getValue( final int row,final String value ) {
194                final String newName = name + HybsSystem.JOINT_STRING + row;
195
196                // TagBufferの連結記述
197                return BASE_HTML
198                                +       new TagBuffer( "textarea" )
199                                                .add( "name"    , newName )
200                                                .add( "id"              , "outdata" )                           // ID 固定です。
201                                                .add( "cols"    , cols2 )
202                                                .add( "rows"    , rows2 )
203                                                .add( tagBuffer.makeTag() )
204                                                .addBody( value )
205                                                .makeTag( row,value );
206        }
207}