Commit d85b70e3 by Lee Jaebin

Merge branch 'features/1.0.500' into feature/1.0.500_34190

# Conflicts:
#	ABVJE_BL/src/jp/agentec/abook/abv/bl/acms/client/AcmsClient.java
#	ABVJE_BL/src/jp/agentec/abook/abv/bl/acms/type/AcmsApis.java
#	ABVJE_UI_Android/src/jp/agentec/abook/abv/ui/common/appinfo/AppDefType.java
#	ABVJE_UI_Android/src/jp/agentec/abook/abv/ui/home/activity/OperationListActivity.java
parents 10472ee2 471da81d
......@@ -23,6 +23,7 @@ import jp.agentec.abook.abv.bl.acms.client.json.GroupsJSON;
import jp.agentec.abook.abv.bl.acms.client.json.LogSendFlagJSON;
import jp.agentec.abook.abv.bl.acms.client.json.NewAppStoreLoginJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationGroupMasterJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ApertureMasterDataJSON;
import jp.agentec.abook.abv.bl.acms.client.json.RequirePasswordChangeJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ResultJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ServerTimeZoneJSON;
......@@ -42,6 +43,7 @@ import jp.agentec.abook.abv.bl.acms.client.parameters.ContentReadingLogParameter
import jp.agentec.abook.abv.bl.acms.client.parameters.EnqueteReplyParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.EnterpriseLoginParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.EnterpriseNewLoginParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetApertureMasterDataParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetContentParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetEnqueteReplyParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetOperationDataParameters;
......@@ -716,6 +718,19 @@ public class AcmsClient implements AcmsClientResponseListener {
return json;
}
/**
* ACMSから、絞り検索マスタデータ情報を取得します。
* @param param {@link AcmsParameters} オブジェクトです。
* @return 絞り検索マスタデータを格納したリストを返します。
* @throws NetworkDisconnectedException
* @throws AcmsException
*/
public ApertureMasterDataJSON getApertureMasterData(GetApertureMasterDataParameters param) throws NetworkDisconnectedException, AcmsException {
HttpResponse response = send(AcmsApis.ApiGetApertureMasterData, param);
return new ApertureMasterDataJSON(response.httpResponseBody);
}
/**********************************************************************************************/
/** 以下、共用メソッド---------------------------------------------------------------------- **/
/**********************************************************************************************/
......
package jp.agentec.abook.abv.bl.acms.client.json;
import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.exception.JSONValidationException;
import org.json.adf.JSONArray;
import org.json.adf.JSONObject;
/**
* {@link AcmsClient#contentVersion} の戻り値です。
* @author Taejin Hong
* @version 1.0.0
*/
public class ApertureMasterDataJSON extends AcmsCommonJSON {
private static final String apertureLastEditDate = "apertureLastEditDate";
private static final String ApertureData = "apertureData";
public String lastEditDate;
public JSONObject apertureData;
public ApertureMasterDataJSON(String jsonString) throws AcmsException {
super(jsonString);
}
@Override
protected void parse(JSONObject json) throws JSONValidationException {
// 絞り検索の日付を取得
if(json.has(apertureLastEditDate)) {
lastEditDate = json.getString(apertureLastEditDate);
}
// 絞り検索のデータを取得
if (json.has(ApertureData)) {
JSONArray apertureList = json.getJSONArray(ApertureData);
for (int i = 0; i < apertureList.length(); i++) {
apertureData = apertureList.getJSONObject(i);
}
}
}
}
package jp.agentec.abook.abv.bl.acms.client.parameters;
/**
* Created by leej on 2018/09/10.
*/
public class GetApertureMasterDataParameters extends AcmsParameters {
public GetApertureMasterDataParameters(String sid) {
super(sid);
}
}
\ No newline at end of file
......@@ -154,6 +154,8 @@ public class AcmsApis {
public static final String ApiSendRoutineTaskData = "routineTaskData";
// 作業種別データ取得
public static final String ApiOperationGroupMaster = "operationGroupMaster";
// 絞り検索マスタデータ取得
public static final String ApiGetApertureMasterData = "getApertureMasterData";
// download
/**
......@@ -197,7 +199,8 @@ public class AcmsApis {
apiValue = Constant.ApiValue.nuapi;
} else if (methodName.equals(ApiOperationList) || methodName.equals(ApiWorkingGroupList) || methodName.equals(ApiSendTaskData) || methodName.equals(ApiGetOperationData) ||
methodName.equals(ApiGetTaskFile) || methodName.equals(ApiSceneEntry) || methodName.equals(ApiTaskContentEntry) ||
methodName.equals(ApiSendPushMessage) || methodName.equals(ApiGetPushMessages) || methodName.equals(ApiSendRoutineTaskData) || methodName.equals(ApiOperationGroupMaster)) {
methodName.equals(ApiSendPushMessage) || methodName.equals(ApiGetPushMessages) || methodName.equals(ApiSendRoutineTaskData) ||
methodName.equals(ApiOperationGroupMaster) || methodName.equals(ApiGetApertureMasterData)) {
apiValue = Constant.ApiValue.checkapi;
}
......
......@@ -179,7 +179,14 @@ public class ABVEnvironment {
public static final boolean DebugContentDownload = false;
public boolean enableToastMessage = true;
// 絞り検索マスタ参照パス
public static final String ApertureMasterDataDirFormat = "%s/ABook/operation/apertureMaster";
// 絞り検索マスタファイル名
public static final String ApertureMasterDataFileName = "apertureMaster.json";
private ABVEnvironment() {
}
......@@ -784,4 +791,11 @@ public class ABVEnvironment {
return reportDate;
}
}
// MasterDataに対したJSONファイルの位置
// 経路:root/files/operation/apertureMaster
public String getMasterFilePath() {
return String.format(ApertureMasterDataDirFormat, rootDirectory);
}
}
......@@ -123,4 +123,9 @@ public class ABookKeys {
// taskReport.Jsonに一時保存フラグを保持するためのキー
public static final String LOCAL_SAVE_FLG = "localSaveFlg";
// 編集画面を
public static final String CMD_EDIT_ATTACHED = "editAttached"; //再編集のためのcmdパラメタ
public static final String EDITABLE = "editable"; //commonAttachedDataUrl()で編集可否を判別するパラメタをWebからもらう。
public static final String FILE_PATH = "filePath"; //再編集する場合、クリックしたイマージのパスのパラメタ
}
......@@ -39,6 +39,10 @@ public class ABVDataCache {
private Date lastPresentTime = DateTimeUtil.getCurrentDate(); // 最後の通信時に取得したサーバの時間
private static final int SEVER_ALERT_INTERVAL = 30; //システム日付チェック前後期間(分)
// Serverから取得したapertureMasterDataのfetchDateを一時的に保存するための変数
private String tempApertureMasterDataFetchDate = null;
/**
* 未指定ジャンルのID
* @since 1.0.0
......@@ -233,6 +237,8 @@ public class ABVDataCache {
defaultCategoryId = -1;
defaultGroupId = -1;
urlPath = null;
// 絞り検索の取得日付を初期化
tempApertureMasterDataFetchDate = null;
}
public void setLastPresentTime(Date lasttime) {
......@@ -371,4 +377,20 @@ public class ABVDataCache {
}
return null;
}
/**
* tempApertureMasterDataFetchDateを更新する
* @param date
*/
public void setTempApertureMasterDataFetchDate(String date){
this.tempApertureMasterDataFetchDate = date;
}
/**
* tempApertureMasterDataFetchDateをreturn
* @return tempApertureMasterDataFetchDate
*/
public String getTempApertureMasterDataFetchDate(){
return tempApertureMasterDataFetchDate;
}
}
......@@ -23,6 +23,7 @@ import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.dto.EnqueteDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ApertureMasterDataLogic;
import jp.agentec.abook.abv.bl.logic.CategoryLogic;
import jp.agentec.abook.abv.bl.logic.ContentLogic;
import jp.agentec.abook.abv.bl.logic.ContentReadingLogLogic;
......@@ -62,7 +63,12 @@ public class ContentRefresher {
private boolean initializingRefreshing = false;
private static final int refreshSleepInterval = 500;
private static final int maxRefreshWorker = 2;
// masterDataを取得するため登録
private ApertureMasterDataLogic apertureMasterDataLogic = AbstractLogic.getLogic(ApertureMasterDataLogic.class);
public static ContentRefresher getInstance() {
if (instance == null) {
synchronized (ContentRefresher.class) {
......@@ -156,6 +162,13 @@ public class ContentRefresher {
contractLogic.initializeContractServiceOption(); // サービスオプション関連処理
groupLogic.initializeGroups(); // グループ設定(グループ変更の場合、FetchDateをクリアする)
categoryLogic.initializeCategories(); // カテゴリ設定
// 絞り検索マスタデータの最新更新された時のFetchDateを一時に保存する。
Logger.d(TAG, "before fetchDate : " + ABVDataCache.getInstance().getTempApertureMasterDataFetchDate());
// CMSでメンテナンスされる絞り検索マスタデータをアプリから取得できるようにJSONファイルを生成する。
apertureMasterDataLogic.initializeApertureMasterData(ABVDataCache.getInstance().getTempApertureMasterDataFetchDate());
Logger.d(TAG, "after fetchDate : " + ABVDataCache.getInstance().getTempApertureMasterDataFetchDate());
if (interrupt) { // この時点で停止要求が来た場合先には進まない。(ServiceOption/Group/Categoryの更新は1セットで行う(トランザクションはそれぞれ別))
Logger.d(TAG, "stop refresh worker before content update.");
......
package jp.agentec.abook.abv.bl.logic;
import org.json.adf.JSONObject;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.acms.client.json.ApertureMasterDataJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetApertureMasterDataParameters;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.FileUtil;
public class ApertureMasterDataLogic extends AbstractLogic {
private static final java.lang.String TAG = "RefineMasterDataLogic";
/**
* グループ情報をサーバから受信し、ローカルに保存します。既存のデータは上書きされます。また、サーバにないグループがローカルにある場合、そのグループは削除されます。
* 絞り検索マスタデータ情報をサーバから受信し、ローカルにJSONで保存する。
* 日付を比べてサーバーからローカルのデータより最新のデータを受信した場合、受信した情報を保存する。
* ローカルの日付はない場合、受信した情報を保存する。
* @param lastFetchDateString
*/
public void initializeApertureMasterData(String lastFetchDateString) {
try {
GetApertureMasterDataParameters param = new GetApertureMasterDataParameters(cache.getMemberInfo().sid);
//サーバーから絞り検索マスタデータを取得
ApertureMasterDataJSON masterDataJson = AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).getApertureMasterData(param);
//サーバーデータの日付
String lastEditDateString = masterDataJson.lastEditDate;
if(lastFetchDateString != null) {
Date lastFetchDate = DateTimeUtil.toDate(lastFetchDateString, "UTC", DateTimeFormat.yyyyMMddHHmmss_hyphen);
Date lastEditDate = DateTimeUtil.toDate(lastEditDateString, "UTC", DateTimeFormat.yyyyMMddHHmmss_hyphen);
if (lastFetchDate == null || lastEditDate.after(lastFetchDate)) {
createApertureMasterDataJson(masterDataJson.apertureData);
cache.setTempApertureMasterDataFetchDate(lastEditDateString);
}
}
else{
createApertureMasterDataJson(masterDataJson.apertureData);
cache.setTempApertureMasterDataFetchDate(lastEditDateString);
}
} catch (Exception e) {
Logger.e(TAG, "apertureMasterDataSend error : ", e);
}
}
/**
* apertureMaster.jsonファイル作成
* @param json
* @throws IOException
*/
private void createApertureMasterDataJson(JSONObject json) throws IOException {
// マスタデータの保存されるパス
String masterDataJsonPath = ABVEnvironment.getInstance().getMasterFilePath() + File.separator + ABVEnvironment.getInstance().ApertureMasterDataFileName;
FileUtil.createFile(masterDataJsonPath, json.toString());
}
}
......@@ -839,6 +839,9 @@ public class OperationLogic extends AbstractLogic {
jsonObject.put("attachedPath", "../../../../files/ABook/operation/" + operationId);
jsonObject.put("attachedMoviePath", ABVEnvironment.getInstance().getAttachedMoviesFilePath(contentId));
// 絞り検索マスタデータのパス
jsonObject.put("masterPath",ABVEnvironment.getInstance().getMasterFilePath() + File.separator + ABVEnvironment.getInstance().ApertureMasterDataFileName);
FileUtil.createFile(contentPath + "/content.json", jsonObject.toString());
}
......
/* drawingboard.js v0.4.6 - https://github.com/Leimi/drawingboard.js
* Copyright (c) 2015 Emmanuel Pelletier
* Licensed MIT */
.drawing-board, .drawing-board * { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; }
.drawing-board-utils-hidden, .drawing-board-controls-hidden { display: none !important; }
.drawing-board { position: relative; display: block; }
.drawing-board-canvas-wrapper { position: relative; margin: 0; border: 1px solid #ddd; }
.drawing-board-canvas { position: absolute; top: 0; left: 0; z-index: 10; width: auto; }
.drawing-board-canvas { cursor: crosshair; z-index: 20; }
.drawing-board-cursor { position: absolute; top: 0; left: 0; pointer-events: none; border-radius: 50%; background: #ccc; background: rgba(0, 0, 0, 0.2); z-index: 30; }
.drawing-board-control > button, .drawing-board-control-colors-rainbows, .drawing-board-control-size .drawing-board-control-inner, .drawing-board-control-size-dropdown { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; overflow: hidden; border: none; background-color: #eee; padding: 2px 4px; border: 1px solid #ccc; box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); -webkit-box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); height: 28px; }
.drawing-board-control > button { cursor: pointer; min-width: 28px; line-height: 14px; }
.drawing-board-control > button:hover, .drawing-board-control > button:focus { background-color: #ddd; }
.drawing-board-control > button:active, .drawing-board-control > button.active { box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.2); -webkit-box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.2); background-color: #ddd; }
.drawing-board-control > button[disabled] { color: gray; }
.drawing-board-control > button[disabled]:hover, .drawing-board-control > button[disabled]:focus, .drawing-board-control > button[disabled]:active, .drawing-board-control > button[disabled].active { background-color: #eee; box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); -webkit-box-shadow: 0 1px 3px -2px #121212, inset 0 2px 5px 0 rgba(255, 255, 255, 0.3); cursor: default; }
/*.drawing-board-controls { margin: 0 auto; text-align: center; font-size: 0; display: table; border-spacing: 9.33333px 0; position: relative; min-height: 28px; }*/
.drawing-board-controls { margin: 0 auto; text-align: center; font-size: 0; display: table; border-spacing: 4px 0; position: relative; min-height: 28px; }
.drawing-board-controls[data-align="left"] { margin: 0; left: -9.33333px; }
.drawing-board-controls[data-align="right"] { margin: 0 0 0 auto; right: -9.33333px; }
.drawing-board-canvas-wrapper + .drawing-board-controls, .drawing-board-controls + .drawing-board-canvas-wrapper { margin-top: 5px; }
.drawing-board-controls-hidden { height: 0; min-height: 0; padding: 0; margin: 0; border: 0; }
.drawing-board-control { display: table-cell; border-collapse: separate; vertical-align: middle; font-size: 16px; height: 100%; }
.drawing-board-control-inner { position: relative; height: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
.drawing-board-control > button { margin: 0; vertical-align: middle; }
.drawing-board-control-colors { font-size: 0; line-height: 0; }
.drawing-board-control-colors-current { border: 1px solid #ccc; cursor: pointer; display: inline-block; width: 26px; height: 26px; }
/*.drawing-board-control-colors-rainbows { display: inline-block; margin-left: 5px; position: absolute; left: 0; top: 33px; margin-left: 0; z-index: 100; width: 250px; height: auto; padding: 4px; }*/
.drawing-board-control-colors-rainbows { display: inline-block; margin-left: 5px; position: absolute; left: 0; top: 33px; margin-left: 0; z-index: 100; width: 180px; height: 42px; padding: 4px; }
/*.drawing-board-control-colors-rainbow { height: 18px; }*/
.drawing-board-control-colors-rainbow { height: 42px; }
/*.drawing-board-control-colors-picker:first-child { margin-right: 5px; }*/
/*.drawing-board-control-colors-picker { display: inline-block; width: 18px; height: 18px; cursor: pointer; }*/
.drawing-board-control-colors-picker { display: inline-block; width: 30px; height: 30px; cursor: pointer; }
/*.drawing-board-control-colors-picker[data-color="rgba(255, 255, 255, 1)"] { width: 17px; height: 16px; border: 1px solid #ccc; border-bottom: none; }*/
/*.drawing-board-control-colors-picker:hover { width: 16px; height: 16px; border: 1px solid #555; }*/
.drawing-board-control-colors-picker:hover { width: 28px; height: 28px; border: 1px solid #555; }
.drawing-board-control-drawingmode > button { margin-right: 2px; }
.drawing-board-control-drawingmode > button:last-child { margin-right: 0; }
.drawing-board-control-drawingmode-pencil-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAK5JREFUeNpiZCADREREOAApEN7AQobmBCA1H8ZnokQzEBxgokBz4ooVKw4wUqB5AYjBSIRmkMYEbJoJGkBIMwiw4NAoAHVyAJLwAnTNWF0A1bwfiA3QNCdis4yRCM0bgJoDcXkTPRrRNV8A+RtfODEi2ayAZIgAVLMj0PYP+AyAuaAAqhEEHInVjBwL8VBb90M1GhKbQlmgqQzk/AdAvBBKEw1YoBoSscUxMQAgwACOZ0Ns854p+gAAAABJRU5ErkJggg=='); background-position: 50% 50%; background-repeat: no-repeat; }
.drawing-board-control-drawingmode-pencil-button:before { content: ""; display: block; width: 0; height: 100%; }
.drawing-board-control-drawingmode-eraser-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMtJREFUeNqck8ENgzAMRZN0gQwSqYwAW+TWMlHVCaC3bMEKrZQFeuuREfpTxciEACmWvowcvQ92zEkUhLX2aowR3vtPeqZKYKQOGvBcpeeyEKYYocY599w1yMBZE/knvDCRB+CZiToIh9BQJRlch0mL8mjRQi8jrCMcPqsuhX97wOA7ig1yXwrTIt2gBxWR2w2TGUwGb+jMiysmC3jaA7TRMZDfyhBnkoWnf4FAMmJXquPCrM5FJm8kgxd0ifC4NVGV6Z1msguH+AowAL10YsD/SG0CAAAAAElFTkSuQmCC'); background-position: 50% 50%; background-repeat: no-repeat; }
.drawing-board-control-drawingmode-eraser-button:before { content: ""; display: block; width: 0; height: 100%; }
.drawing-board-control-drawingmode-filler-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnNJREFUeNp0k0trE1EUx89MJpNJooYYXBgDNtCKdRPwlbqoCKUtaNVNA0Uo7UbMxoVPEARTXEi+QWfnwn6DEAlEkrSLttTGRiULEQlJ8yChmbzI++E50yTUJA78uMy953/u/557LmOz2WDEZ2m1WrckSRJSqdR2tVrdHQyYebwHtVoNuFHqTqczhQnWKaBYLDoKhcIuzgHDMKBSqeD20qd+LNdsNocSoFhRr9ctpVLJigl4xIIJQizLAmG4cAPa7bYcy9Iug5TL5UYikbD6/X7Rbre/IUcYe3WUW5ZsnQQzW9LpNOPz+UQc5aBM5mgdh7vI9FCCAesW2tnr9YqZTAby+bw8f3AQRP6853n+Ph5hemSCntjj8YjZbFYWx2IxeS2RSEMwuA87O79eqdXquVolK+GxnP0EPbHb7RZJSGABIR6PA11zJHKIR2MhHA5DIPDj7eH3j95KpfK60Wg8Yntil8slkqgnpioLghacTidoNDpEC3q9HnheCc3s1jZeLcW943pirPw/4lKpBkqlDubnl/riycnLsLy88EKj0fhzuRyZv8RFo1E6wpBYkiqy7Z54YmIcVlYeyOKC4mYwJ0nHRaQuM5vNT6hB/iceG7sIq6sPnwmC4MerDkby40AOCCoiddie1Wp92W7zQ2KTyQSLizNP8T0EsPLBbxEDnCj0GkM2qIEwyZRCobizsfH5A1ZXFhuN52F29vpz3HkL574mk8lj24Y5wsHkvjjoX0BOIWc5jruHzbK2ufmzEwpFO3jnDhQv4JoROYdoERVyGjEgZ8iBDlF3FzXo4go6utZ9lftY4N/dXisjR0i1G0ublv8KMAA0ZoUlicxrhwAAAABJRU5ErkJggg=='); background-position: 50% 50%; background-repeat: no-repeat; }
.drawing-board-control-drawingmode-filler-button:before { content: ""; display: block; width: 0; height: 100%; }
.drawing-board-control-navigation > button { font-family: Helvetica, Arial, sans-serif; font-size: 14px; font-weight: bold; margin-right: 2px; }
.drawing-board-control-navigation > button:last-child { margin-right: 0; }
.drawing-board-control-size[data-drawing-board-type="range"] .drawing-board-control-inner { width: 75px; }
.drawing-board-control-size[data-drawing-board-type="dropdown"] .drawing-board-control-inner { overflow: visible; }
.drawing-board-control-size-range-input { position: relative; width: 100%; z-index: 100; margin: 0; padding: 0; border: 0; }
.drawing-board-control-size-range-current, .drawing-board-control-size-dropdown-current span, .drawing-board-control-size-dropdown span { display: block; background: #333; opacity: .8; }
.drawing-board-control-size-range-current { display: inline-block; opacity: .15; position: absolute; pointer-events: none; left: 50%; top: 50%; z-index: 50; }
.drawing-board-control-size-dropdown-current { display: block; height: 100%; width: 40px; overflow: hidden; position: relative; }
.drawing-board-control-size-dropdown-current span { position: absolute; left: 50%; top: 50%; }
/*.drawing-board-control-size-dropdown { position: absolute; left: 0px; top: 33px; height: auto; list-style-type: none; margin: 0; padding: 0; z-index: 100; width: 40px;}*/
.drawing-board-control-size-dropdown { position: absolute; left: -6px; top: 33px; height: auto; list-style-type: none; margin: 0; padding: 0; z-index: 100; width: 60px;}
.drawing-board-control-size-dropdown li { display: block; padding: 4px; margin: 3px 0; min-height: 16px; }
.drawing-board-control-size-dropdown li:hover { background: #ccc; }
.drawing-board-control-size-dropdown span { margin: auto; display: inline-block; vertical-align: middle;}
.drawing-board-control-download-button { overflow: hidden; *text-indent: -9999px; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ1JREFUeNpiYMADIiIiGkAYnxomBvygHorJNoAgGI4GAEM9AYSJFWdEU2QApM5DuYlAPB8L23DFihUX4AZA4xkUVY5AiQNAPkhhAg4XLwCqSQSqcQCy9wNxI4YXQApACnFpJioQsRiCVTPeWIBqmADCuDSDAAu+KAJqLCQUjcgGGAADh9joN0A24AOU3U9GOvrAghRYAqRqBukFCDAAdsY3kbu0QI0AAAAASUVORK5CYII='); background-position: 50% 50%; background-repeat: no-repeat; }
.drawing-board-control-download-button:before { content: ""; display: block; width: 0; height: 100%; }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>AIS Edit Tool</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<meta name="viewport" content="height=device-height">
<link rel="stylesheet" href="./css/drawingboard.css">
<style>
.board {
margin: 0 auto;
}
</style>
<style>
#ais-edit-tool {
height: 90vh; /* For 90% screen height */
width: 90vw; /* For 90% screen width */
}
</style>
<style>
.drawing-board-canvas-wrapper {
border: 1px solid gray;
}
#overlay{
position:initial;
display:block;
width:100%;
height:100%;
z-index:30;
}
</style>
</head>
<body>
<noscript>JavaScript is required :(</noscript>
<div class="container">
<div>
<div class="board" id="ais-edit-tool">
</div>
</div>
</div>
<script src="./js/jquery.min.js"></script>
<script src="./js/simple-undo.js"></script>
<script src="./js/utils.js"></script>
<script src="./js/drawingboard.js"></script>
<script src="./js/controls/control.js"></script>
<script src="./js/controls/color.js"></script>
<script src="./js/controls/drawingmode.js"></script>
<script src="./js/controls/navigation.js"></script>
<script src="./js/controls/size.js"></script>
<script src="./js/controls/download.js"></script>
<script>
var aisEditTool = new DrawingBoard.Board('ais-edit-tool', {
controls: [
'Color',
{ Size: { type: 'dropdown' } },
{ DrawingMode: { filler: false } },
'Download'
],
color: '#ff0000',
background: false,
size: 3,
webStorage: 'false',
controlsPosition: 'center',
enlargeYourContainer: true
});
//Canvasのサイズを写真の横縦割合に合わせて変更
function resizeCanvasToRatio(ratio){
aisEditTool.resizeCanvasToRatio(ratio);
}
//CanvasのBackgroundをイメージファイルのurlに設定
function setBackground(url){
aisEditTool.setBackground(url);
}
//Canvasの修正可否を返す。
function isCanvasEdited(){
return aisEditTool.isCanvasEdited();
}
//パスを取得してoverlayイメージをCanvasの中に入れる。(iOS)
function createOverlayImageElement(imageSrc) {
aisEditTool.createOverlayImageElement(imageSrc);
}
//接続しているクライアントがPCかmobileかをはんだんする
function checkPC() {
var filter = "win16|win32|win64|mac|macintel";
if ( navigator.platform ) {
if ( filter.indexOf( navigator.platform.toLowerCase() ) < 0 ) {
//mobile
return false;
} else {
//pc
return true;
}
}
}
//このペースのロード完了後でイメージをロードする
document.addEventListener("DOMContentLoaded", function(event) {
console.log('DOMContentLoaded');
if(checkPC()){
parent.loadDlgImage(); //call parent, parent call setBackground
}
});
</script>
</body>
</html>
DrawingBoard.Control.Color = DrawingBoard.Control.extend({
name: 'colors',
initialize: function() {
this.initTemplate();
var that = this;
this.$el.on('click', '.drawing-board-control-colors-picker', function(e) {
var color = $(this).attr('data-color');
that.board.setColor(color);
that.$el.find('.drawing-board-control-colors-current')
.css('background-color', color)
.attr('data-color', color);
that.board.ev.trigger('color:changed', color);
that.$el.find('.drawing-board-control-colors-rainbows').addClass('drawing-board-utils-hidden');
e.preventDefault();
});
this.$el.on('click', '.drawing-board-control-colors-current', function(e) {
that.$el.find('.drawing-board-control-colors-rainbows').toggleClass('drawing-board-utils-hidden');
e.preventDefault();
});
$('body').on('click', function(e) {
var $target = $(e.target);
var $relatedButton = $target.hasClass('drawing-board-control-colors-current') ? $target : $target.closest('.drawing-board-control-colors-current');
var $myButton = that.$el.find('.drawing-board-control-colors-current');
var $popup = that.$el.find('.drawing-board-control-colors-rainbows');
if ( (!$relatedButton.length || $relatedButton.get(0) !== $myButton.get(0)) && !$popup.hasClass('drawing-board-utils-hidden') )
$popup.addClass('drawing-board-utils-hidden');
});
},
initTemplate: function() {
var tpl = '<div class="drawing-board-control-inner">' +
'<div class="drawing-board-control-colors-current" style="background-color: {{color}}" data-color="{{color}}"></div>' +
'<div class="drawing-board-control-colors-rainbows">{{rainbows}}</div>' +
'</div>';
var oneColorTpl = '<div class="drawing-board-control-colors-picker" data-color="{{color}}" style="background-color: {{color}}"></div>';
var rainbows = '';
// $.each([0.75, 0.5, 0.25], $.proxy(function(key, val) {
$.each([0.5], $.proxy(function(key, val) {
var i = 0;
var additionalColor = null;
rainbows += '<div class="drawing-board-control-colors-rainbow">';
// if (val == 0.25) additionalColor = this._rgba(0, 0, 0, 1);
// if (val == 0.5) additionalColor = this._rgba(150, 150, 150, 1);
// if (val == 0.75) additionalColor = this._rgba(255, 255, 255, 1);
// rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: additionalColor.toString() });
// while (i <= 330) {
// rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: this._hsl2Rgba(this._hsl(i-60, 1, val)).toString() });
// i+=30;
// }
// white, black, red, blue, yellow
var white = this._rgba(255,255,255,1);
var black = this._rgba(0,0,0,1);
var red = this._rgba(255,0,0,1);
var blue = this._rgba(0,0,255,1);
var yellow = this._rgba(255,255,0,1);
rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: white.toString()});
rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: black.toString()});
rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: red.toString()});
rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: blue.toString()});
rainbows += DrawingBoard.Utils.tpl(oneColorTpl, {color: yellow.toString()});
rainbows += '</div>';
}, this));
this.$el.append( $( DrawingBoard.Utils.tpl(tpl, {color: this.board.color, rainbows: rainbows }) ) );
this.$el.find('.drawing-board-control-colors-rainbows').addClass('drawing-board-utils-hidden');
},
onBoardReset: function(opts) {
this.board.setColor(this.$el.find('.drawing-board-control-colors-current').attr('data-color'));
},
_rgba: function(r, g, b, a) {
return { r: r, g: g, b: b, a: a, toString: function() { return "rgba(" + r +", " + g + ", " + b + ", " + a + ")"; } };
},
_hsl: function(h, s, l) {
return { h: h, s: s, l: l, toString: function() { return "hsl(" + h +", " + s*100 + "%, " + l*100 + "%)"; } };
},
_hex2Rgba: function(hex) {
var num = parseInt(hex.substring(1), 16);
return this._rgba(num >> 16, num >> 8 & 255, num & 255, 1);
},
//conversion function (modified a bit) taken from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
_hsl2Rgba: function(hsl) {
var h = hsl.h/360, s = hsl.s, l = hsl.l, r, g, b;
function hue2rgb(p, q, t) {
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
if (s === 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = Math.floor( (hue2rgb(p, q, h + 1/3)) * 255);
g = Math.floor( (hue2rgb(p, q, h)) * 255);
b = Math.floor( (hue2rgb(p, q, h - 1/3)) * 255);
}
return this._rgba(r, g, b, 1);
}
});
\ No newline at end of file
DrawingBoard.Control = function(drawingBoard, opts) {
this.board = drawingBoard;
this.opts = $.extend({}, this.defaults, opts);
this.$el = $(document.createElement('div')).addClass('drawing-board-control');
if (this.name)
this.$el.addClass('drawing-board-control-' + this.name);
this.board.ev.bind('board:reset', $.proxy(this.onBoardReset, this));
this.initialize.apply(this, arguments);
return this;
};
DrawingBoard.Control.prototype = {
name: '',
defaults: {},
initialize: function() {
},
addToBoard: function() {
this.board.addControl(this);
},
onBoardReset: function(opts) {
}
};
//extend directly taken from backbone.js
DrawingBoard.Control.extend = function(protoProps, staticProps) {
var parent = this;
var child;
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
$.extend(child, parent, staticProps);
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate();
if (protoProps) $.extend(child.prototype, protoProps);
child.__super__ = parent.prototype;
return child;
};
\ No newline at end of file
DrawingBoard.Control.Download = DrawingBoard.Control.extend({
name: 'download',
initialize: function() {
this.$el.append('<button class="drawing-board-control-download-button"></button>');
this.$el.on('click', '.drawing-board-control-download-button', $.proxy(function(e) {
this.board.downloadImg();
e.preventDefault();
}, this));
}
});
\ No newline at end of file
DrawingBoard.Control.DrawingMode = DrawingBoard.Control.extend({
name: 'drawingmode',
defaults: {
pencil: true,
eraser: true,
filler: true
},
initialize: function() {
this.prevMode = this.board.getMode();
$.each(["pencil", "eraser", "filler"], $.proxy(function(k, value) {
if (this.opts[value]) {
this.$el.append('<button class="drawing-board-control-drawingmode-' + value + '-button" data-mode="' + value + '"></button>');
}
}, this));
this.$el.on('click', 'button[data-mode]', $.proxy(function(e) {
var value = $(e.currentTarget).attr('data-mode');
var mode = this.board.getMode();
if (mode !== value) this.prevMode = mode;
var newMode = mode === value ? this.prevMode : value;
this.board.setMode( newMode );
e.preventDefault();
}, this));
this.board.ev.bind('board:mode', $.proxy(function(mode) {
this.toggleButtons(mode);
}, this));
this.toggleButtons( this.board.getMode() );
},
toggleButtons: function(mode) {
this.$el.find('button[data-mode]').each(function(k, item) {
var $item = $(item);
$item.toggleClass('active', mode === $item.attr('data-mode'));
});
}
});
DrawingBoard.Control.Navigation = DrawingBoard.Control.extend({
name: 'navigation',
defaults: {
back: true,
forward: true,
reset: true
},
initialize: function() {
var el = '';
if (this.opts.back) el += '<button class="drawing-board-control-navigation-back">&larr;</button>';
if (this.opts.forward) el += '<button class="drawing-board-control-navigation-forward">&rarr;</button>';
if (this.opts.reset) el += '<button class="drawing-board-control-navigation-reset">&times;</button>';
this.$el.append(el);
if (this.opts.back) {
var $back = this.$el.find('.drawing-board-control-navigation-back');
this.board.ev.bind('historyNavigation', $.proxy(this.updateBack, this, $back));
this.$el.on('click', '.drawing-board-control-navigation-back', $.proxy(function(e) {
this.board.goBackInHistory();
e.preventDefault();
}, this));
this.updateBack($back);
}
if (this.opts.forward) {
var $forward = this.$el.find('.drawing-board-control-navigation-forward');
this.board.ev.bind('historyNavigation', $.proxy(this.updateForward, this, $forward));
this.$el.on('click', '.drawing-board-control-navigation-forward', $.proxy(function(e) {
this.board.goForthInHistory();
e.preventDefault();
}, this));
this.updateForward($forward);
}
if (this.opts.reset) {
this.$el.on('click', '.drawing-board-control-navigation-reset', $.proxy(function(e) {
this.board.reset({ background: true });
e.preventDefault();
}, this));
}
},
updateBack: function($back) {
if (this.board.history.canUndo()) {
$back.removeAttr('disabled');
} else {
$back.attr('disabled', 'disabled');
}
},
updateForward: function($forward) {
if (this.board.history.canRedo()) {
$forward.removeAttr('disabled');
} else {
$forward.attr('disabled', 'disabled');
}
}
});
\ No newline at end of file
DrawingBoard.Control.Size = DrawingBoard.Control.extend({
name: 'size',
defaults: {
type: "auto",
// dropdownValues: [1, 3, 6, 10, 20, 30, 40, 50],
dropdownValues: [3, 6, 10, 20, 30, 45],
min: 1,
max: 50
},
types: ['dropdown', 'range'],
initialize: function() {
if (this.opts.type == "auto")
this.opts.type = this._iHasRangeInput() ? 'range' : 'dropdown';
var tpl = $.inArray(this.opts.type, this.types) > -1 ? this['_' + this.opts.type + 'Template']() : false;
if (!tpl) return false;
this.val = this.board.opts.size;
this.$el.append( $( tpl ) );
this.$el.attr('data-drawing-board-type', this.opts.type);
this.updateView();
var that = this;
if (this.opts.type == "range") {
this.$el.on('change', '.drawing-board-control-size-range-input', function(e) {
that.val = $(this).val();
that.updateView();
that.board.ev.trigger('size:changed', that.val);
e.preventDefault();
});
}
if (this.opts.type == "dropdown") {
this.$el.on('click', '.drawing-board-control-size-dropdown-current', $.proxy(function(e) {
this.$el.find('.drawing-board-control-size-dropdown').toggleClass('drawing-board-utils-hidden');
}, this));
this.$el.on('click', '[data-size]', function(e) {
that.val = parseInt($(this).attr('data-size'), 0);
that.updateView();
that.board.ev.trigger('size:changed', that.val);
e.preventDefault();
});
}
},
_rangeTemplate: function() {
var tpl = '<div class="drawing-board-control-inner" title="{{size}}">' +
'<input type="range" min="{{min}}" max="{{max}}" value="{{size}}" step="1" class="drawing-board-control-size-range-input">' +
'<span class="drawing-board-control-size-range-current"></span>' +
'</div>';
return DrawingBoard.Utils.tpl(tpl, {
min: this.opts.min,
max: this.opts.max,
size: this.board.opts.size
});
},
_dropdownTemplate: function() {
var tpl = '<div class="drawing-board-control-inner" title="{{size}}">' +
'<div class="drawing-board-control-size-dropdown-current"><span></span></div>' +
'<ul class="drawing-board-control-size-dropdown">';
$.each(this.opts.dropdownValues, function(i, size) {
tpl += DrawingBoard.Utils.tpl(
'<li data-size="{{size}}"><span style="width: {{size}}px; height: {{size}}px; border-radius: {{size}}px;"></span></li>',
{ size: size }
);
});
tpl += '</ul></div>';
return tpl;
},
onBoardReset: function(opts) {
this.updateView();
},
updateView: function() {
var val = this.val;
this.board.ctx.lineWidth = val;
this.$el.find('.drawing-board-control-size-range-current, .drawing-board-control-size-dropdown-current span').css({
width: val + 'px',
height: val + 'px',
borderRadius: val + 'px',
marginLeft: -1*val/2 + 'px',
marginTop: -1*val/2 + 'px'
});
this.$el.find('.drawing-board-control-inner').attr('title', val);
if (this.opts.type == 'dropdown') {
var closest = null;
$.each(this.opts.dropdownValues, function(i, size) {
if (closest === null || Math.abs(size - val) < Math.abs(closest - val))
closest = size;
});
this.$el.find('.drawing-board-control-size-dropdown').addClass('drawing-board-utils-hidden');
}
},
_iHasRangeInput: function() {
var inputElem = document.createElement('input'),
smile = ':)',
docElement = document.documentElement,
inputElemType = 'range',
available;
inputElem.setAttribute('type', inputElemType);
available = inputElem.type !== 'text';
inputElem.value = smile;
inputElem.style.cssText = 'position:absolute;visibility:hidden;';
if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
docElement.appendChild(inputElem);
defaultView = document.defaultView;
available = defaultView.getComputedStyle &&
defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
(inputElem.offsetHeight !== 0);
docElement.removeChild(inputElem);
}
return !!available;
}
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
(function() {
'use strict';
/**
* SimpleUndo is a very basic javascript undo/redo stack for managing histories of basically anything.
*
* options are: {
* * `provider` : required. a function to call on `save`, which should provide the current state of the historized object through the given "done" callback
* * `maxLength` : the maximum number of items in history
* * `onUpdate` : a function to call to notify of changes in history. Will be called on `save`, `undo`, `redo` and `clear`
* }
*
*/
var SimpleUndo = function(options) {
var settings = options ? options : {};
var defaultOptions = {
provider: function() {
throw new Error("No provider!");
},
maxLength: 30,
onUpdate: function() {}
};
this.provider = (typeof settings.provider != 'undefined') ? settings.provider : defaultOptions.provider;
this.maxLength = (typeof settings.maxLength != 'undefined') ? settings.maxLength : defaultOptions.maxLength;
this.onUpdate = (typeof settings.onUpdate != 'undefined') ? settings.onUpdate : defaultOptions.onUpdate;
this.initialItem = null;
this.clear();
};
function truncate (stack, limit) {
while (stack.length > limit) {
stack.shift();
}
}
SimpleUndo.prototype.initialize = function(initialItem) {
this.stack[0] = initialItem;
this.initialItem = initialItem;
};
SimpleUndo.prototype.clear = function() {
this.stack = [this.initialItem];
this.position = 0;
this.onUpdate();
};
SimpleUndo.prototype.save = function() {
this.provider(function(current) {
if (this.position >= this.maxLength) truncate(this.stack, this.maxLength);
this.position = Math.min(this.position,this.stack.length - 1);
this.stack = this.stack.slice(0, this.position + 1);
this.stack.push(current);
this.position++;
this.onUpdate();
}.bind(this));
};
SimpleUndo.prototype.undo = function(callback) {
if (this.canUndo()) {
var item = this.stack[--this.position];
this.onUpdate();
if (callback) {
callback(item);
}
}
};
SimpleUndo.prototype.redo = function(callback) {
if (this.canRedo()) {
var item = this.stack[++this.position];
this.onUpdate();
if (callback) {
callback(item);
}
}
};
SimpleUndo.prototype.canUndo = function() {
return this.position > 0;
};
SimpleUndo.prototype.canRedo = function() {
return this.position < this.count();
};
SimpleUndo.prototype.count = function() {
return this.stack.length - 1; // -1 because of initial item
};
//exports
// node module
if (typeof module != 'undefined') {
module.exports = SimpleUndo;
}
// browser global
if (typeof window != 'undefined') {
window.SimpleUndo = SimpleUndo;
}
})();
\ No newline at end of file
window.DrawingBoard = typeof DrawingBoard !== "undefined" ? DrawingBoard : {};
DrawingBoard.Utils = {};
/*!
* Tim (lite)
* github.com/premasagar/tim
*//*
A tiny, secure JavaScript micro-templating script.
*/
DrawingBoard.Utils.tpl = (function(){
"use strict";
var start = "{{",
end = "}}",
path = "[a-z0-9_][\\.a-z0-9_]*", // e.g. config.person.name
pattern = new RegExp(start + "\\s*("+ path +")\\s*" + end, "gi"),
undef;
return function(template, data){
// Merge data into the template string
return template.replace(pattern, function(tag, token){
var path = token.split("."),
len = path.length,
lookup = data,
i = 0;
for (; i < len; i++){
lookup = lookup[path[i]];
// Property not found
if (lookup === undef){
throw "tim: '" + path[i] + "' not found in " + tag;
}
// Return the required value
if (i === len - 1){
return lookup;
}
}
});
};
}());
/**
* https://github.com/jeromeetienne/microevent.js
* MicroEvent - to make any js object an event emitter (server or browser)
*
* - pure javascript - server compatible, browser compatible
* - dont rely on the browser doms
* - super simple - you get it immediatly, no mistery, no magic involved
*
* - create a MicroEventDebug with goodies to debug
* - make it safer to use
*/
DrawingBoard.Utils.MicroEvent = function(){};
DrawingBoard.Utils.MicroEvent.prototype = {
bind : function(event, fct){
this._events = this._events || {};
this._events[event] = this._events[event] || [];
this._events[event].push(fct);
},
unbind : function(event, fct){
this._events = this._events || {};
if( event in this._events === false ) return;
this._events[event].splice(this._events[event].indexOf(fct), 1);
},
trigger : function(event /* , args... */){
this._events = this._events || {};
if( event in this._events === false ) return;
for(var i = 0; i < this._events[event].length; i++){
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
}
}
};
//I know.
DrawingBoard.Utils._boxBorderSize = function($el, withPadding, withMargin, direction) {
withPadding = !!withPadding || true;
withMargin = !!withMargin || false;
var width = 0,
props;
if (direction == "width") {
props = ['border-left-width', 'border-right-width'];
if (withPadding) props.push('padding-left', 'padding-right');
if (withMargin) props.push('margin-left', 'margin-right');
} else {
props = ['border-top-width', 'border-bottom-width'];
if (withPadding) props.push('padding-top', 'padding-bottom');
if (withMargin) props.push('margin-top', 'margin-bottom');
}
for (var i = props.length - 1; i >= 0; i--)
width += parseInt($el.css(props[i]).replace('px', ''), 10);
return width;
};
DrawingBoard.Utils.boxBorderWidth = function($el, withPadding, withMargin) {
return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'width');
};
DrawingBoard.Utils.boxBorderHeight = function($el, withPadding, withMargin) {
return DrawingBoard.Utils._boxBorderSize($el, withPadding, withMargin, 'height');
};
DrawingBoard.Utils.isColor = function(string) {
if (!string || !string.length) return false;
return (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i).test(string) || $.inArray(string.substring(0, 3), ['rgb', 'hsl']) !== -1;
};
/**
* Packs an RGB color into a single integer.
*/
DrawingBoard.Utils.RGBToInt = function(r, g, b) {
var c = 0;
c |= (r & 255) << 16;
c |= (g & 255) << 8;
c |= (b & 255);
return c;
};
/**
* Returns informations on the pixel located at (x,y).
*/
DrawingBoard.Utils.pixelAt = function(image, x, y) {
var i = (y * image.width + x) * 4;
var c = DrawingBoard.Utils.RGBToInt(
image.data[i],
image.data[i + 1],
image.data[i + 2]
);
return [
i, // INDEX
x, // X
y, // Y
c // COLOR
];
};
/**
* Compares two colors with the given tolerance (between 0 and 255).
*/
DrawingBoard.Utils.compareColors = function(a, b, tolerance) {
if (tolerance === 0) {
return (a === b);
}
var ra = (a >> 16) & 255, rb = (b >> 16) & 255,
ga = (a >> 8) & 255, gb = (b >> 8) & 255,
ba = a & 255, bb = b & 255;
return (Math.abs(ra - rb) <= tolerance)
&& (Math.abs(ga - gb) <= tolerance)
&& (Math.abs(ba - bb) <= tolerance);
};
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
}());
......@@ -1402,4 +1402,9 @@
<string name="Report_5">報告(5)</string>
<string name="Routine_5">定期点検(5)</string>
<string name="ReportReply_5">報告(回答)(5)</string>
<!--編集画面-->
<string name="msg_confirm_close_edit_page">編集を終了しますか?\n(保存されていない変更は破棄されます。)</string>
<string name="msg_error_edit_page_save">ファイルの保存中に予想以外のエラーが発生しました。\n編集画面を終了します。</string>
<string name="msg_error_edit_page_open">編集画面の表示に失敗しました。</string>
</resources>
......@@ -1410,4 +1410,9 @@
<string name="Report_5">보고(5)</string>
<string name="Routine_5">정기점검(5)</string>
<string name="ReportReply_5">보고(응답)(5)</string>
<!--編集画面-->
<string name="msg_confirm_close_edit_page">편집을 종료하시겠습니까?\n(저장되지 않은 변경 사항은 삭제됩니다.)</string>
<string name="msg_error_edit_page_save">파일 저장 중에 예기치 않은 오류가 발생했습니다.\n편집창을 종료합니다.</string>
<string name="msg_error_edit_page_open">편집창을 여는데 실패했습니다.</string>
</resources>
\ No newline at end of file
......@@ -1408,4 +1408,10 @@
<string name="Report_5">Report(5)</string>
<string name="Routine_5">Routine(5)</string>
<string name="ReportReply_5">ReportReply(5)</string>
<!--編集画面-->
<string name="msg_confirm_close_edit_page">Are you sure you want to finish editing?\n(Unsaved changes will be discarded.)</string>
<string name="msg_error_edit_page_save">An unexpected error has occurred while saving the image.\nClosing the editing Page.</string>
<string name="msg_error_edit_page_open">Failed to open the edit tool.</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/photoEditDialog"
style="@style/Theme_CustomProgressDialog"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:orientation="vertical">
<WebView
android:id="@+id/edit_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageButton
android:id="@+id/edit_page_close_btn"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="top|right"
android:layout_marginRight="7dp"
android:layout_marginTop="7dp"
android:background="@color/operation_search_button_color"
android:clickable="true"
android:elevation="0dp"
android:src="@drawable/btn_close"
android:tint="@color/background" />
</FrameLayout>
......@@ -8,7 +8,10 @@ import android.support.multidex.MultiDexApplication;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.cl.helper.ABVUncaughtExceptionHandler;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.util.Initializer;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.adf.util.FileUtil;
......@@ -49,6 +52,9 @@ public class ABVApplication extends MultiDexApplication {
//添付ファイル臨時保存場所削除
FileUtil.delete(ABVEnvironment.getInstance().getCacheTempAttachedImageDirPath());
// 絞り検索のfetchDateをローカルに保存された値を取得して設定する
ABVDataCache.getInstance().setTempApertureMasterDataFetchDate(PreferenceUtil.getUserPref(this, AppDefType.UserPrefKey.APERTURE_MASTER_DATA_FETCH_DATE, null));
}
@Override
......
......@@ -28,6 +28,7 @@ import org.json.adf.JSONObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
......@@ -35,7 +36,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import jp.agentec.abook.abv.bl.acms.client.json.content.ContentJSON;
import jp.agentec.abook.abv.bl.acms.type.OperationType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.Callback;
......@@ -74,9 +74,9 @@ import jp.agentec.abook.abv.ui.home.helper.ABookCheckWebViewHelper;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.viewer.activity.CheckOZDViewActivity;
import jp.agentec.abook.abv.ui.viewer.activity.HTMLWebViewActivity;
import jp.agentec.abook.abv.ui.viewer.activity.HTMLXWalkWebViewActivity;
import jp.agentec.abook.abv.ui.viewer.activity.NoPdfViewActivity;
import jp.agentec.abook.abv.ui.viewer.activity.PhotoEditActivity;
import jp.agentec.abook.abv.ui.viewer.foxitPdf.FoxitPdfCore;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.FileUtil;
......@@ -139,6 +139,12 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
public int mButtonStatus; // 保存ボタンチェック
protected boolean mAddReport; // 作業追加区分
// 編集
protected String mEditFilePath; //再編集する時、Webからもらうクリックしたイメージファイルのパス
protected String mEnablePhotoEdit; //最初ファイルをアップロードする時、Webからもらう編集可能可否のパラメタ 0:編集する。 1:編集しない。
protected PhotoEditActivity mPhotoEditDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -859,6 +865,7 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
}
public void commonShouldOverrideUrlLoading (Uri uri, OperationTaskDto operationTaskDto) {
Logger.d(TAG, "Uri : %s", uri);
//parent method
Map<String, String> abookCheckParam = new HashMap<String, String>();
for (String key : uri.getQueryParameterNames()) {
......@@ -1000,7 +1007,14 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
}
} else if (mCmd.equals(ABookKeys.CMD_SAVE_ATTACHED)) {
mAttachedFileName = abookCheckParam.get(ABookKeys.FILE_NAME);
//編集可否を判別
mEnablePhotoEdit = abookCheckParam.get(ABookKeys.EDITABLE) == null ? "0" : abookCheckParam.get(ABookKeys.EDITABLE); //添付したファイルの編集可否のパラメタ
getAttachedDataUrl();
} else if (mCmd.equals(ABookKeys.CMD_EDIT_ATTACHED)){
//編集パラメタ(
mAttachedFileName = abookCheckParam.get(ABookKeys.FILE_NAME); //再編集するファイルの名
mEditFilePath = abookCheckParam.get(ABookKeys.FILE_PATH); //再編集するファイルのパス
openEditPage();
} else if (mCmd.equals(ABookKeys.CMD_SHOW_REPORT_OZD)) {
mReportFileName = abookCheckParam.get(ABookKeys.REPORT_FILE_NAME);
// 作業報告画面改善
......@@ -1084,6 +1098,10 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
FileUtil.delete(mLocalFile);
}
mLocalFile = null;
//編集可能可否をチェックする。
if (mEnablePhotoEdit.equals("1")) { //編集の場合、編集画面を開ける。
commonOpenEditPage();
}
} catch (Exception e) {
isError = true;
Logger.e(TAG, e);
......@@ -1151,6 +1169,10 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
});
}
public void openEditPage(){
webViewLoadUrl("javascript:android.openEditPage()");
}
/**
* 位置情報取得
* @param showPermissionDialogFlg
......@@ -1308,4 +1330,59 @@ public abstract class ABVContentViewActivity extends ABVAuthenticatedActivity {
}
}
}
/**
* 下位のWebviewからコールする編集画面
*/
public void commonOpenEditPage(){
//ダイアローグの上、新しいViewを作るため、Threadで実行する。Threadを使わない場合エラー発 生
runOnUiThread(new Runnable() {
@Override
public void run() {
//添付した写真はTempパスにある。
//保存されてある写真はoperationフォルダにある。
//保存されてある写真を修正する場合、ファイルをTempにコピーした後に編集する。
final String tempImagePath = ABVEnvironment.getInstance().getTempFilePath(getContentId(), mTaskKey, mAttachedFileName); //添付ファイルのTempパス
String savedImagePath = ABVEnvironment.getInstance().getOperationTaskReportLevelDirPath(mOperationId, mTaskKey,0) + "/" + mAttachedFileName; //保存された写真のパス
//保存されたイメージがあり、編集したいイメージのパスがTempがない場合、ファイルをTempにコピー
// パスがTempと一緒の場合、イメージが一回以上修正され、上書きしない。
if(FileUtil.exists(savedImagePath) && !mEditFilePath.equals(tempImagePath)){
try {
FileUtil.copy(savedImagePath,tempImagePath,true); //保存されたファイルをTempパスにコピー
} catch (IOException e) {
e.printStackTrace();
return;
}
}
if(FileUtil.exists(tempImagePath)){ //Tempパスにファイルがある場合、編集を実行
//編集画面をコール
PhotoEditActivity dialog = new PhotoEditActivity(ABVContentViewActivity.this, tempImagePath); //ロードして編集するイメージのパスを設定
showPhotoEditDialog(dialog);
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
//Web Cacheが更新されて編集画面のダイアローグ閉じた後、JavascriptにてImgタグを再生成してThumbnailを更新
webViewLoadUrl(String.format("javascript:document.getElementById('reportForm').contentWindow.changeThumbnailTagForAnd('%s','%s')", mAttachedFileName, tempImagePath));
afterABookCheckApi(mCmd, mTaskKey, 0, "", null);
mPhotoEditDialog = null;
}
});
}
else{
Logger.e(TAG, "image file is not found");
showSimpleAlertDialog(R.string.error,R.string.msg_error_edit_page_open);
}
}
});
}
protected void showPhotoEditDialog(PhotoEditActivity photoEditDialog) {
if (this.mPhotoEditDialog != null) {
this.mPhotoEditDialog.dismiss();
}
else {
this.mPhotoEditDialog = photoEditDialog;
this.mPhotoEditDialog.show();
}
}
}
......@@ -62,8 +62,11 @@ public interface AppDefType {
String OPERATION_REPORT_TYPES = "operationReportTypes";
String RESOURCE_PATTERN_TYPE = "resourcePatternType"; // 文言リソースパターン
String OPERATION_GROUP_MASERT_MODE = "operation_group_master"; // 通常・作業種別モード(画面)
String OPERATION_GROUP_MASERT_ID = "operation_group_master_id"; // 作業種別のID
String APERTURE_MASTER_DATA_FETCH_DATE = "apertureMasterDataFetchDate"; // 絞り検索マスタデータのFetchDate
}
/**
......
......@@ -54,7 +54,9 @@ import java.util.List;
import java.util.Map;
import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.acms.client.json.ApertureMasterDataJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationDataJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetApertureMasterDataParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetOperationDataParameters;
import jp.agentec.abook.abv.bl.acms.type.DownloadStatusType;
import jp.agentec.abook.abv.bl.acms.type.OperationType;
......@@ -88,6 +90,7 @@ import jp.agentec.abook.abv.bl.dto.TaskDto;
import jp.agentec.abook.abv.bl.dto.TaskReportDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.OperationGroupMasterLogic;
import jp.agentec.abook.abv.bl.logic.ApertureMasterDataLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.bl.logic.PushMessageLogic;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
......@@ -199,6 +202,11 @@ public class OperationListActivity extends ABVUIActivity {
// 作業種別のサービスオプション値を保持用フラグ
private boolean mOperationGroupMasterServiceOperationFlg;
// 絞り検索マスタデータ
// private Date mApertureLastEditDate;
// 絞り検索マスタLogic
private ApertureMasterDataLogic mApertureMasterDataLogic = AbstractLogic.getLogic(ApertureMasterDataLogic.class);
// ビューの作成
private class ReloadHandler implements Runnable {
@Override
......@@ -465,6 +473,9 @@ public class OperationListActivity extends ABVUIActivity {
getABVUIDataCache().saveLastUpdateTime();
// リソースパターンを取得し、ローカルに保存する。
setResourcePattern();
// 絞り検索マスタデータ最新更新する時fetchDateをローカルに保存する。
setApertureMasterDataFetchDate();
if (mOperationGroupMasterServiceOperationFlg == ABVDataCache.getInstance().serviceOption.isOperationGroupMaster()) {
// サービスオプションが変わってない場合は、ビューは作らずにデータのみ更新
refreshOperationList();
......@@ -718,6 +729,9 @@ public class OperationListActivity extends ABVUIActivity {
mOperationLogic.createJsonForOpenABookCheckPano(operationDto.operationId, operationDto.contentId, contentPath);
mOperationLogic.createJsonForOperationContent(operationDto.operationId, contentPath, operationDto.reportType == ReportType.RoutineTask);
// 絞り検索マスタデータを受信、JSONファイルを生成
mApertureMasterDataLogic.initializeApertureMasterData(ABVDataCache.getInstance().getTempApertureMasterDataFetchDate());
// サーバ作業後、対応必要
StringBuffer path = new StringBuffer();
path.append(contentPath);
......@@ -2161,4 +2175,11 @@ public class OperationListActivity extends ABVUIActivity {
break;
}
}
/**
* 絞り検索の日付を設定
*/
private void setApertureMasterDataFetchDate() {
putUserPref(AppDefType.UserPrefKey.APERTURE_MASTER_DATA_FETCH_DATE, ABVDataCache.getInstance().getTempApertureMasterDataFetchDate());
}
}
......@@ -486,6 +486,11 @@ public class HTMLWebViewActivity extends ParentWebViewActivity {
public void getAttachedDataUrl(String data) {
commonAttachedDataUrl(data);
}
@JavascriptInterface
public void openEditPage() {
commonOpenEditPage();
}
}
@Override
......
......@@ -525,6 +525,11 @@ public class HTMLXWalkWebViewActivity extends ParentWebViewActivity {
public void getAttachedDataUrl(String data) {
commonAttachedDataUrl(data);
}
@org.xwalk.core.JavascriptInterface
public void openEditPage() {
commonOpenEditPage();
}
}
@Override
......
......@@ -5,7 +5,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.view.View;
import android.webkit.ValueCallback;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
......@@ -34,7 +33,6 @@ import jp.agentec.abook.abv.cl.util.ContentLogUtil;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.activity.ABVContentViewActivity;
import jp.agentec.abook.abv.ui.common.activity.ABVUIActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
......@@ -136,13 +134,17 @@ public class ParentWebViewActivity extends ABVContentViewActivity {
boolean isError = false;
if (data != null) {
try {
String imagePath = ABVEnvironment.getInstance().getTempFilePath(getContentId(), mTaskKey, mAttachedFileName);
final String imagePath = ABVEnvironment.getInstance().getTempFilePath(getContentId(), mTaskKey, mAttachedFileName);
ABookCheckWebViewHelper.getInstance().decodeToImage(data, imagePath);
//アプリ内のファイルのみ削除(Galleryファイルは削除しない)
if (mLocalFile != null && mLocalFile.getPath().contains(getPackageName())) {
FileUtil.delete(mLocalFile);
}
mLocalFile = null;
//編集可能可否をチェックする。
if (mEnablePhotoEdit == 0) { //編集の場合、編集画面を開ける。
commonOpenEditPage();
}
} catch (Exception e) {
isError = true;
Logger.e(TAG, e);
......
......@@ -533,5 +533,10 @@ public class OperationTaskLayout extends RelativeLayout {
public void getAttachedDataUrl(String data) {
((ABVContentViewActivity) OperationTaskLayout.this.mContext).commonAttachedDataUrl(data);
}
@JavascriptInterface
public void openEditPage() {
((ABVContentViewActivity) OperationTaskLayout.this.mContext).commonOpenEditPage();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment