package open.dolphin.client; import java.awt.Color; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.io.*; import java.util.HashMap; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JPopupMenu; import javax.swing.border.Border; import javax.swing.text.Position; import open.dolphin.infomodel.*; import open.dolphin.order.StampEditor; import open.dolphin.project.Project; import open.dolphin.util.ZenkakuUtils; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; /** * KartePane に Component として挿入されるスタンプを保持スルクラス。 * * @author Kazushi Minagawa, Digital Globe, Inc. */ public final class StampHolder extends AbstractComponentHolder implements ComponentHolder { private static final String KEY_MODEL = "model"; private static final String KEY_HINTS = "hints"; private static final String KEY_STAMP_NAME = "stampName"; private static final String KEY_STAMP_HOLDER = "stmpHolder"; private static final String KEY_ENCODING = "UTF-8"; private static final String DOT_VM = ".vm"; private static final Color FOREGROUND = new Color(20, 20, 140); private static final Color BACKGROUND = Color.white; //masuda^ private static final Border nonSelectedBorder = BorderFactory.createLineBorder(GUIConst.STAMP_HOLDER_NON_SELECTED_BORDER); private static final Border selectedBorder = BorderFactory.createLineBorder(GUIConst.STAMP_HOLDER_SELECTED_BORDER); //masuda$ private ModuleModel stamp; private StampRenderingHints hints; private final KartePane kartePane; private Position start; private Position end; private boolean selected; private final Color foreGround = FOREGROUND; private final Color background = BACKGROUND; ////s.oh^ 2014/09/30 スタンプの色変更 // private static final Color STAMP_1 = new Color(255, 255, 153); // private static final Color STAMP_2 = new Color(255, 255, 204); // private static final Color STAMP_3 = new Color(204, 255, 255); // private static final Color STAMP_4 = new Color(204, 236, 255); // private static final Color STAMP_5 = new Color(153, 204, 255); // private static final Color STAMP_6 = new Color(255, 204, 204); // private static final Color STAMP_7 = new Color(234, 234, 234); // private static final Color STAMP_8 = new Color(255, 204, 153); ////s.oh$ /** Creates new StampHolder2 * @param kartePane * @param stamp */ public StampHolder(KartePane kartePane, ModuleModel stamp) { super(); this.kartePane = kartePane; StampRenderingHints h = new StampRenderingHints(); h.setShowStampName(Project.getBoolean("karte.show.stampName")); setHints(h); setForeground(foreGround); setBackground(background); //masuda^ setBorder(nonSelectedBorder); //masuda$ ////s.oh^ 2014/09/30 スタンプの色変更 // if(Project.getBoolean(Project.CHANGE_STAMP_COLOR)) { // switch(stamp.getModuleInfoBean().getEntity()) { // case IInfoModel.ENTITY_PHYSIOLOGY_ORDER: // case IInfoModel.ENTITY_BACTERIA_ORDER: // case IInfoModel.ENTITY_LABO_TEST: // h.setLabelColor(STAMP_1); // break; // case IInfoModel.ENTITY_TREATMENT: // h.setLabelColor(STAMP_2); // break; // case IInfoModel.ENTITY_SURGERY_ORDER: // h.setLabelColor(STAMP_3); // break; // case IInfoModel.ENTITY_RADIOLOGY_ORDER: // h.setLabelColor(STAMP_4); // break; // case IInfoModel.ENTITY_BASE_CHARGE_ORDER: // h.setLabelColor(STAMP_5); // break; // case IInfoModel.ENTITY_INSTRACTION_CHARGE_ORDER: // h.setLabelColor(STAMP_6); // break; // case IInfoModel.ENTITY_MED_ORDER: // h.setLabelColor(STAMP_7); // break; // case IInfoModel.ENTITY_INJECTION_ORDER: // h.setLabelColor(STAMP_8); // break; // default: // break; // } // } ////s.oh$ setStamp(stamp); } /** * Popupメニューを表示する。 * @param e */ @Override public void mabeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { JPopupMenu popup = new JPopupMenu(); ChartMediator mediator = kartePane.getMediator(); popup.add(mediator.getAction(GUIConst.ACTION_CUT)); popup.add(mediator.getAction(GUIConst.ACTION_COPY)); //s.oh^ 2014/04/16 メニュー制御 mediator.getAction(GUIConst.ACTION_COPY).setEnabled(true); //s.oh$ // copyAsText java.util.ResourceBundle bundle = ClientContext.getMyBundle(StampHolder.class); String actionText = bundle.getString("actionText.copyAsText"); AbstractAction copyAsTextAction = new AbstractAction(actionText) { @Override public void actionPerformed(ActionEvent ae) { IInfoModel im = stamp.getModel(); if (im instanceof BundleDolphin) { BundleDolphin bundle = (BundleDolphin)im; StringSelection ss = new StringSelection(bundle.toString()); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); } } }; popup.add(copyAsTextAction); //s.oh^ 2014/01/27 スタンプのテキストコピー機能拡張 if(Project.getBoolean("stamp.text.copy.patid")) { // copyAsTextAndPatID actionText = bundle.getString("actionText.copyAsTextWithPatientId"); AbstractAction copyAsTextAndOtherAction = new AbstractAction(actionText) { @Override public void actionPerformed(ActionEvent ae) { IInfoModel im = stamp.getModel(); if (im instanceof BundleDolphin) { BundleDolphin bundle = (BundleDolphin)im; StringSelection ss = null; if(kartePane.getPatID() != null) { ss = new StringSelection(bundle.toString(kartePane.getPatID(), getStamp().getModuleInfoBean().getStampName())); }else{ ss = new StringSelection(bundle.toString()); } Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); } } }; popup.add(copyAsTextAndOtherAction); } //s.oh$ popup.add(mediator.getAction(GUIConst.ACTION_PASTE)); // 編集可の時のみ actionText = bundle.getString("actionText.edit"); if (kartePane.getTextPane().isEditable()) { popup.addSeparator(); // 右クリックで編集 AbstractAction editAction = new AbstractAction(actionText) { @Override public void actionPerformed(ActionEvent ae) { edit(); } }; popup.add(editAction); } popup.show(e.getComponent(), e.getX(), e.getY()); } } /** * このスタンプホルダの * @return KartePaneを返す。 */ @Override public KartePane getKartePane() { return kartePane; } /** * スタンプホルダのコンテントタイプを返す。 * @return */ @Override public int getContentType() { return ComponentHolder.TT_STAMP; } /** * このホルダのモデルを返す。 * @return */ public ModuleModel getStamp() { return stamp; } /** * このホルダのモデルを設定する。 * @param stamp */ public void setStamp(ModuleModel stamp) { if (this.stamp!=stamp) { this.stamp = stamp; } setMyText(); } /** * Itemを追加しtextを再描画する * @param items */ public void addItems(ClaimItem[] items) { if (stamp!=null && items!=null) { ClaimBundle bundle = (ClaimBundle)stamp.getModel(); for (ClaimItem ci : items) { bundle.addClaimItem(ci); } setMyText(); } } public StampRenderingHints getHints() { return hints; } public void setHints(StampRenderingHints hints) { this.hints = hints; } /** * 選択されているかどうかを返す。 * @return 選択されている時 true */ @Override public boolean isSelected() { return selected; } /** * 選択属性を設定する。 * @param selected 選択の時 true */ @Override public void setSelected(boolean selected) { boolean old = this.selected; this.selected = selected; //masuda^ if (selected) { this.setBorder(selectedBorder); this.selected = true; } else { this.setBorder(nonSelectedBorder); this.selected = false; } //masuda } /** * KartePane でこのスタンプがダブルクリックされた時コールされる。 * StampEditor を開いてこのスタンプを編集する。 */ @Override public void edit() { if (kartePane.getTextPane().isEditable()) { StampEditor nse = new StampEditor(stamp, StampHolder.this); } } /** * エディタで編集した値を受け取り内容を表示する。 * @param e */ @Override public void propertyChange(PropertyChangeEvent e) { Object newStamp = e.getNewValue(); // スタンプを置き換える if (newStamp!=null) { importStamp((ModuleModel)newStamp); } } /** * スタンプの内容を置き換える。 * @param newStamp */ public void importStamp(ModuleModel newStamp) { // 処方でまとめるかどうか boolean merge = Project.getBoolean("merge.rp.with.sameAdmin"); merge = merge && (newStamp.getModuleInfoBean().getEntity().equals(IInfoModel.ENTITY_MED_ORDER)); //s.oh^ 2013/02/22 不具合修正(同じ用法がマージされない) setStamp(newStamp); //s.oh$ if (merge) { StampHolder sh = kartePane.findCanMergeRpHolder(this); if (sh!=null) { // newStampのclaimItemをshへ追加する sh.addItems(((BundleMed)newStamp.getModel()).getClaimItem()); // このStampは削除する //s.oh^ 2013/11/26 スクロールバーのリセット //kartePane.removeStamp(this); kartePane.removeStamp(this, false); //s.oh$ return; } } //s.oh^ 2014/01/27 同じ検体検査をまとめる // boolean mergeLabTest = Project.getBoolean(Project.KARTE_MERGE_WITH_LABTEST, false); // mergeLabTest = mergeLabTest && (newStamp.getModuleInfoBean().getEntity().equals(IInfoModel.ENTITY_LABO_TEST)); // if (mergeLabTest) { // StampHolder sh = kartePane.findCanMergeLabTestHolder(this); // // if (sh!=null) { // // newStampのclaimItemをshへ追加する // sh.addItems(((BundleDolphin)newStamp.getModel()).getClaimItem()); // // // このStampは削除する // kartePane.removeStamp(this, false); // return; // } // } //s.oh$ //s.oh^ 2013/02/22 不具合修正(同じ用法がマージされない) //setStamp(newStamp); //s.oh$ kartePane.setDirty(true); kartePane.getTextPane().validate(); kartePane.getTextPane().repaint(); } /** * TextPane内での開始と終了ポジションを保存する。 * @param start * @param end */ @Override public void setEntry(Position start, Position end) { this.start = start; this.end = end; } /** * 開始ポジションを返す。 * @return */ @Override public int getStartPos() { return start.getOffset(); } /** * 終了ポジションを返す。 * @return */ @Override public int getEndPos() { return end.getOffset(); } /** * Velocity を利用してスタンプの内容を表示する。 */ private void setMyText() { if (getStamp()==null) { return; } try { IInfoModel model = getStamp().getModel(); VelocityContext context = ClientContext.getVelocityContext(); context.put(KEY_MODEL, model); context.put(KEY_HINTS, getHints()); context.put(KEY_STAMP_NAME, getStamp().getModuleInfoBean().getStampName()); //s.oh^ 2014/02/03 撮影分割数対応 Map<String, String> items = new HashMap<>(); if(((BundleDolphin)model).getClaimItem() != null) { for(ClaimItem item : ((BundleDolphin)model).getClaimItem()) { if(item.getCode().startsWith("7") && item.getNumber().indexOf("-") > 0) { items.put(item.getCode(), item.getNumber()); item.setNumber(item.getNumber().split("-")[0]); } } } //s.oh$ String templateFile = getStamp().getModel().getClass().getName() + DOT_VM; // このスタンプのテンプレートファイルを得る if (getStamp().getModuleInfoBean().getEntity()!=null) { if (getStamp().getModuleInfoBean().getEntity().equals(IInfoModel.ENTITY_LABO_TEST)) { if (Project.getBoolean("laboFold", true)) { templateFile = "labo.vm"; } } } // Merge する StringWriter sw = new StringWriter(); BufferedReader reader; try (BufferedWriter bw = new BufferedWriter(sw)) { InputStream instream = ClientContext.getTemplateAsStream(templateFile); reader = new BufferedReader(new InputStreamReader(instream, KEY_ENCODING)); Velocity.evaluate(context, bw, KEY_STAMP_HOLDER, reader); bw.flush(); } reader.close(); // 全角数字とスペースを直す String text = sw.toString(); this.setText(ZenkakuUtils.toHalfNumber(text)); // カルテペインへ展開された時広がるのを防ぐ this.setMaximumSize(this.getPreferredSize()); //s.oh^ 2014/02/03 撮影分割数対応 if(((BundleDolphin)model).getClaimItem() != null) { for(ClaimItem item : ((BundleDolphin)model).getClaimItem()) { if(item.getCode().startsWith("7")) { String data = items.get(item.getCode()); if(data != null && data.length() > 0) { item.setNumber(data); } } } } //s.oh$ } catch (ParseErrorException | MethodInvocationException | ResourceNotFoundException | IOException e) { //e.printStackTrace(System.err); } } }