/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package controlador; import controlador.apoios.GuardaPadraoBrM; import controlador.apoios.InfoDiagrama; import controlador.apoios.TreeItem; import controlador.inspector.InspectorItemBase; import controlador.inspector.InspectorItemExtender; import controlador.inspector.InspectorProperty; import desenho.Ancorador; import desenho.Elementar; import desenho.FormaElementar; import desenho.formas.Desenhador; import desenho.formas.Forma; import desenho.formas.FormaTextoBase.AlinhamentoTexto; import desenho.formas.Legenda; import desenho.linhas.SuperLinha; import desenho.preAnyDiagrama.PreTexto.TipoTexto; import diagramas.conceitual.Texto; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Cursor; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.image.BufferedImage; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; import java.io.StringWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import util.BoxingJava; import util.Utilidades; import util.XMLGenerate; /** * * @author Rick */ public class Diagrama implements Serializable, ClipboardOwner { private static final long serialVersionUID = 21212121212121L; /** * Classes existentes. */ private final Class[] classesDoDiagrama = new Class[]{}; public Class[] getCassesDoDiagrama() { return classesDoDiagrama; } // <editor-fold defaultstate="collapsed" desc="Campos"> protected transient Editor master; private int baseRecuo = 3; private boolean draging = false; protected Color pontoCor = Color.BLACK; protected Color pontoCorMultSel = Color.GREEN; protected FormaElementar infoDiagrama = null; public static final String VERSAO_A = "3"; public static final String VERSAO_B = "2"; public static final String VERSAO_C = "0"; protected String versaoA = Diagrama.VERSAO_A; protected String versaoB = Diagrama.VERSAO_B; protected String versaoC = Diagrama.VERSAO_C; private TipoDeDiagrama tipo = TipoDeDiagrama.tpConceitual; transient private String nome; transient private String Arquivo = ""; //mostra uma grade no modelo. private Font font; private Color foreColor = Elementar.defaultColor; private int heigth = 4096; private int width = 4096; private double zoom = 1.0; //private Color background = Color.WHITE; private Ancorador superAncorador = null; public Cursor getCursor() { return this.master.getBox().getCursor(); } public void setCursor(Cursor cursor) { if (getComando() != null) { this.master.getBox().setCursor(getEditor().getControler().MakeCursor(getComando())); return; } this.master.getBox().setCursor(cursor); } /** * @return the pontoWidth */ public int getPontoWidth() { return master.getBox().getPontoWidth(); } /** * @return the pontoHeigth */ public int getPontoHeigth() { return master.getBox().getPontoHeigth(); } public Color getBackground() { return master.getBox().getBackground(); } // public void setBackground(Color getBackground) { // this.background = getBackground; // } public Color getForeColor() { return foreColor; } public void setForeColor(Color foreColor) { this.foreColor = foreColor; } public Font getFont() { return font; } public void setFont(Font font) { this.font = font; } public int getHeight() { return heigth; } public int getWidth() { return width; } /** * Ao verificar-se o total de itens em um Diagrama, para saber se algum foi incluído, é preciso exluir do total aqueles que fazem parte do próprio objto. Até então apenas o InfoDiagrama. */ public static final int totalInicialDeItens = 1; public String getArquivo() { return Arquivo; } public void setArquivo(String Arquivo) { this.Arquivo = Arquivo; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; if (master != null) { master.RePopuleBarraDiagramas(false); } } public void SetNome(String nome) { this.nome = nome; } public TipoDeDiagrama getTipo() { return tipo; } protected void setTipo(TipoDeDiagrama tipo) { this.tipo = tipo; } public String getTipoDeDiagramaFormatado() { // if (getTipo() == TipoDeDiagrama.tpConceitual || getTipo() == TipoDeDiagrama.tpFisico || getTipo() == TipoDeDiagrama.tpLogico) { // return Editor.fromConfiguracao.getValor("Inspector.obj.modelo.tipo") + " " + Editor.fromConfiguracao.getValor("Inspector.lst.tipomodelo." + getTipo().name().substring(2).toLowerCase()); // } return Editor.fromConfiguracao.getValor("Inspector.lst.tipodiagrama." + getTipo().name().substring(2).toLowerCase()); } public String getVersao() { return versaoA + "." + versaoB + "." + versaoC; } public boolean isMostrarInfoDiagrama() { return infoDiagrama.isVisible(); } public void setMostrarInfoDiagrama(boolean mostrarInfoDiagrama) { this.infoDiagrama.setVisible(mostrarInfoDiagrama); } public Editor getEditor() { return master; } public Color getPontoCorMultSel() { return pontoCorMultSel; } public void setPontoCorMultSel(Color pc) { this.pontoCorMultSel = pc; } public Color getPontoCor() { return pontoCor; } public void setPontoCor(Color pontoCor) { this.pontoCor = pontoCor; } /** * @return the editorBackColor */ public final Color getEditorBackColor() { return master.getBox().getBackground(); } /** * @return the baseRecuo */ public int getBaseRecuo() { return baseRecuo; } /** * @param baseRecuo the baseRecuo to set */ public void setBaseRecuo(int baseRecuo) { this.baseRecuo = baseRecuo; } protected ArrayList<Elementar> subItens = new ArrayList<>(); public ArrayList<Elementar> getSubItens() { return subItens; } protected ArrayList<FormaElementar> ListaDeItens = new ArrayList<>(); public ArrayList<FormaElementar> getListaDeItens() { return ListaDeItens; } private ArrayList<FormaElementar> itensSelecionados = new ArrayList<>(); public ArrayList<FormaElementar> getItensSelecionados() { return itensSelecionados; } // </editor-fold> public Diagrama(Editor omaster) { super(); master = omaster; font = Elementar.CloneFont(this.master.getBox().getFont()); isLoadCreate = true; infoDiagrama = new InfoDiagrama(this); infoDiagrama.SetBounds(5, 5, 300, 150); isLoadCreate = false; heigth = master.getBox().EditorMaxHeigth; width = master.getBox().EditorMaxWidth; meusComandos.add(Controler.Comandos.cmdDesenhador.name()); meusComandos.add(Controler.Comandos.cmdLegenda.name()); meusComandos.add(Controler.Comandos.cmdTexto.name()); meusComandos.add(Controler.Comandos.cmdApagar.name()); nome = ""; superAncorador = new Ancorador(this); superAncorador.SetBounds(50, 50, 18, 36); } public final ArrayList<String> meusComandos = new ArrayList<>(); public void setMaster(Editor master) { this.master = master; } int _tick = 0; private void tick() { _tick++; } /** * @return the zoom */ public double getZoom() { return zoom; } /** * @param zoom the zoom to set */ public void setZoom(double zoom) { this.zoom = zoom; } private void PinteGrade(Graphics2D g) { int w = master.getGridWidth(); int gW = (getWidth() / w) + 1; int gH = (getHeight() / w) + 1; int ww = getWidth(); int hh = getHeight(); Paint bkppaint = g.getPaint(); g.setColor(new Color(241, 246, 251)); for (int i = 1; i < gW; i++) { g.drawLine(w * i, 0, w * i, hh); } for (int i = 1; i < gH; i++) { g.drawLine(0, w * i, ww, w * i); } g.setPaint(bkppaint); // Paint bkppaint = g.getPaint(); // g.setColor(new Color(241, 246, 251)); // final Rectangle rv = getEditor().getBox().getVisibleRect(); // // int w = master.getGridWidth(); // int gW = (rv.width / w) + 2; // int gH = (rv.height / w) + 2; // // int le = (rv.x - (rv.x % w)); // final int hh = rv.y + rv.height; // for (int i = 0; i < gW; i++) { // g.drawLine(le, rv.y, le, hh); // le+= w; // } // // int to = (rv.y - (rv.y % w)); // final int ww = rv.x + rv.width; // for (int i = 0; i < gH; i++) { // g.drawLine(rv.x, to, ww, to); // to+= w; // } // //// int w = master.getGridWidth(); //// int gW = (getWidth() / w) + 1; //// int gH = (getHeight() / w) + 1; //// Rectangle rv = getEditor().getBox().getVisibleRect(); //// //// int ww = getWidth(); //// int hh = getHeight(); //// //// Paint bkppaint = g.getPaint(); //// g.setColor(new Color(241, 246, 251)); //// //// for (int i = 1; i < gW; i++) { //// //// g.drawLine(w * i, 0, w * i, hh); //// } //// //// for (int i = 1; i < gH; i++) { //// g.drawLine(0, w * i, ww, w * i); //// } // // g.setPaint(bkppaint); } /** * Mostra a área de impressão no diagrama * * @param g * @param wdt largura * @param ht altura */ public void PaintAI(Graphics2D g, int wdt, int ht) { Paint bkppaint = g.getPaint(); g.setColor(new Color(221, 221, 221)); int w = wdt; while (w < getWidth()) { g.drawLine(w, 1, w, getHeight() - 1); w += wdt; } int h = ht; while (h < getHeight()) { g.drawLine(1, h, getWidth() - 1, h); h += ht; } g.setPaint(bkppaint); } /** * Não deve ser salvo. Trata-se de uma lista de elementos visíveis para criar uma navegação */ private transient TreeItem TreeNavegacao = null; /** * Atualiza uma lista de elementos visíveis para criar uma navegação. * * @param atualisar a lista: (sim | não) * @return */ public TreeItem AtualizeTreeNavegacao(boolean atualisar) { if (atualisar || TreeNavegacao == null) { TreeNavegacao = new TreeItem(getNomeFormatado()); getListaDeItens().stream().filter((it) -> (it instanceof Forma)).map(it -> (Forma) it).forEach((it) -> { it.MostreSeParaExibicao(TreeNavegacao); }); } return TreeNavegacao; } /** * Trata-se de uma lista de elementos visíveis para criar uma navegação * * @return [lista de elementos] */ public TreeItem getTreeNavegacao() { return AtualizeTreeNavegacao(false); } public void SelecioneByID(int i, boolean mostrar) { FormaElementar e = FindByID(i); if (e == null) { master.AtualizeTreeNavegacao(); return; } DiagramaDoSelecao(e, false, false); if (mostrar) { master.Mostre(e.getLocation()); } } /** * Quando InfoDigrama gera as propriedades ele as informa ao modelo, possibilitando a inclusão de algum comando. * * @param res propriedades ainda não preenchidas */ public void BeginProperty(ArrayList<InspectorProperty> res) { } /** * Quando InfoDigrama gera as propriedades ele as informa ao modelo, possibilitando a inclusão de algum comando. * * @param res propriedades já preenchidas */ public void EndProperty(ArrayList<InspectorProperty> res) { } /** * Quando InfoDigrama roda o DoAnyThing() ela chama este método no Diagrama, * * @param Tag - vem do DoAnyThing do InfoDiagrama */ public void DoAnyThing(int Tag) { } /** * Insere comandos no submenu "menuCMD" (Comandos) do menu diagrama. O menu "item" é um submenu a ser populado. * * @param item Implementado, como exemplo em DiagramaEap */ public void populeComandos(JMenuItem item) { item.setEnabled(false); } /** * Roda um comando criado pelo AcaoDiagrama. * * @param comm qualquer comando em formato string. Implementado, como exemplo em DiagramaEap */ public void rodaComando(String comm) { } public int getID() { return infoDiagrama.getID(); } public String getUniversalUnicID() { return ((InfoDiagrama) infoDiagrama).getDiagramaUniversalUnicID(); } public final void ReGeraUniversalUnicID() { ((InfoDiagrama) infoDiagrama).ReGeraGuardaUnicDiagramaID(); } public String getNomeFormatado() { return getNome().isEmpty() ? "<<" + getTipoDeDiagramaFormatado() + ">>" : getNome(); } /** * Método para setar um valor String diretamente no diagrama, disparado pelo InfoDiagrama * * @param str * @param tag */ public void setFromString(String str, int tag) { //# talvez implantar o setFromInt e etc. } /** * Rodado após o carregamento do diagrama a aprtir de um arquivo. será ultil no futuro para setar propriedades default em novas versões dos diagramas a partir das versões do brMOdelo. roda dentro do método: ProcessePosOpen(Diagrama res) na classe Editor */ public void OnAfterLoad(boolean isXml) { } public enum TipoDeDiagrama { tpConceitual, tpLogico, tpFluxo, tpAtividade, tpEap, tpLivre } public boolean isAlterado() { return (this.getListaDeItens().size() > Diagrama.totalInicialDeItens || this.getMudou() || !("".equals(this.getArquivo()))); } // <editor-fold defaultstate="collapsed" desc="Eventos"> public void ProcessPaint(Graphics2D Canvas) { //Canvas.drawString(Integer.toString(_tick), 200, 200); double z = master.getBox().getZoom(); Canvas.scale(z, z); if (master.isShowGrid()) { PinteGrade(Canvas); } if (master.getBox().isMostrarAreaImpressao()) { PaintAI(Canvas, master.getBox().areaImpressaoWidth, master.getBox().areaImpressaoHeigth); } for (int i = subItens.size() - 1; i > -1; i--) { Elementar e = subItens.get(i); if (e.CanPaint()) { e.DoPaint(Canvas); } } superAncorador.DoPaint(Canvas); } public void ExternalPaint(Graphics g) { RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); renderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); renderHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); Graphics2D Canvas = (Graphics2D) g; Canvas.addRenderingHints(renderHints); Canvas.setStroke(new BasicStroke( 1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); Canvas.setPaint(Color.BLACK); for (int i = subItens.size() - 1; i > -1; i--) { Elementar e = subItens.get(i); if (e.CanPaint()) { e.DoPaint(Canvas); } } } public void ExternalPaintSelecao(Graphics g) { RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); renderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); renderHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); Graphics2D Canvas = (Graphics2D) g; Canvas.addRenderingHints(renderHints); Canvas.setStroke(new BasicStroke( 1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); Canvas.setPaint(Color.BLACK); for (int i = getItensSelecionados().size() - 1; i > -1; i--) { FormaElementar e = getItensSelecionados().get(i); e.HidePontos(true); if (e.CanPaint()) { e.DoPaint(Canvas); } e.HidePontos(false); } } /** * Máxima região pintada X e Y * * @return Point */ public Point getPontoExtremo() { final int borda = 4; int rX = 0; int rY = 0; for (FormaElementar el : ListaDeItens) { rX = Math.max(rX, el.getLeftWidth()); rY = Math.max(rY, el.getTopHeight()); } if (rX > 0) { rX += borda; } if (rY > 0) { rY += borda; } return new Point(rX, rY); } /** * Máxima região pintada dentre os selecionados. X e Y * * @return Point */ public Point getPontoExtremoSelecionado() { final int borda = 4; int rX = 0; int rY = 0; for (FormaElementar el : getItensSelecionados()) { rX = Math.max(rX, el.getLeftWidth()); rY = Math.max(rY, el.getTopHeight()); } if (rX > 0) { rX += borda; } if (rY > 0) { rY += borda; } return new Point(rX, rY); } public Point getPontoMenorSelecionado() { int rX = getWidth(); int rY = getHeight(); for (FormaElementar el : getItensSelecionados()) { rX = Math.min(rX, el.getLeft()); rY = Math.min(rY, el.getTop()); } return new Point(rX, rY); } public void mouseClick(MouseEvent e) { // if (tmp.isMyEvent(e)) { //Usar mouse pressed! // tmp.mouseClicked(e); // } } public void mouseDblClick(MouseEvent e) { e = tradutorZoom(e); //elementarSobMouse = CaptureFromPoint(e.getPoint()); setElementarSobMouse((superAncorador.IsMe(e.getPoint()) ? superAncorador : CaptureFromPoint(e.getPoint()))); if (elementarSobMouse != null) { elementarSobMouse.mouseDblClicked(e); } } public void mousePressed(MouseEvent e) { master.requestFocus(); e = tradutorZoom(e); if (comando != null) { isLoadCreate = true; RealiseComando(e.getPoint()); isLoadCreate = false; if (cliq1 == null) { DoMuda(null); } return; } if (!((elementarSobMouse != null) && (elementarSobMouse == elementarSobMouse.IsMeOrMine(e.getPoint())))) { setElementarSobMouse(CaptureFromPoint(e.getPoint())); } if (elementarSobMouse != null) { elementarSobMouse.mousePressed(e); draging = true; if (elementarSobMouse != superAncorador) { superAncorador.SetVisible(false); //não precisa repintar! } } else { DiagramaDownPos.setLocation(e.getPoint()); isMouseDown = true; master.InitMultiSel(DiagramaDownPos); } } public void mouseEntered(MouseEvent e) { //processaMouseEntredExited(e, elementarSobMouse, true);//não precisa } public void mouseExited(MouseEvent e) { processaMouseEntredExited(e, elementarSobMouse, false); } private void processaMouseEntredExited(MouseEvent ev, Elementar el, boolean enter) { ev = tradutorZoom(ev); if (el != null) { if (enter) { el.mouseEntered(ev); } else { el.mouseExited(ev); } } } public void mouseDragged(MouseEvent e) { e = tradutorZoom(e); if (draging && (elementarSobMouse != null)) { elementarSobMouse.mouseDragged(e); return; } if (isMouseDown) { int x = e.getX(); int y = e.getY(); final int ALeft = (x < DiagramaDownPos.x) ? x : DiagramaDownPos.x; final int ATop = (y < DiagramaDownPos.y) ? y : DiagramaDownPos.y; final int AWidth = Math.abs(x - DiagramaDownPos.x); final int AHeight = Math.abs(y - DiagramaDownPos.y); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { master.getMultSel().setBounds(ALeft, ATop, AWidth, AHeight); master.repaint(); } }); } } /** * Método que aplica o fator de zoom nas coordenadas do mouse. * * @param e evento do Mouse (geralmente interessa apenas as coordenadas); * @return novo evento com novas coordenadas */ protected MouseEvent tradutorZoom(MouseEvent e) { double z = 1.0 / getZoom(); Point p = new Point((int) (e.getX() * z), (int) (e.getY() * z)); MouseEvent ex = new MouseEvent(master.getBox(), e.getID(), e.getWhen(), e.getModifiers(), p.x, p.y, e.getClickCount(), false); return ex; } /** * Método que aplica o fator de zoom nas coordenadas e. * * @param e = ponto (geralmente coordenadas); * @return novo ponto */ protected Point tradutorZoom(Point e) { double z = 1.0 / getZoom(); return new Point((int) (e.x * z), (int) (e.y * z)); } /** * Dado um retângulo ele é converido para as coordenadas na tela no caso do diagrma estar ampliado ou reduzido (Zoom) * * @param r retângulo a converter. * @return retângulo convertido. */ public Rectangle ZoomRectangle(Rectangle r) { double z = getZoom(); return new Rectangle((int) (r.x * z), (int) (r.y * z), (int) (r.width * z), (int) (r.height * z)); } public void mouseMoved(MouseEvent e) { if (isMouseDown || draging) { mouseReleased(e); return; } e = tradutorZoom(e); Elementar olde = elementarSobMouse; // elementarSobMouse = CaptureFromPoint(e.getPoint()); setElementarSobMouse((superAncorador.IsMe(e.getPoint()) ? superAncorador : CaptureFromPoint(e.getPoint()))); if (elementarSobMouse != null) { elementarSobMouse.mouseMoved(e); } else { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } if (comando != null) { Elementar composicao = elementarSobMouse; if (composicao != null && elementarSobMouse.isComposto()) { composicao = composicao.ProcessaComposicao(e.getPoint()); } ProcessaOverDraw(false, composicao); } else if (olde != elementarSobMouse) { processaMouseEntredExited(e, olde, false); processaMouseEntredExited(e, elementarSobMouse, true); } } private FormaElementar overDraw = null; public Rectangle AlmentarRetangulo(Rectangle r, int x, int y) { return Utilidades.Grow(r, x, y, 0); } /** * Colore uma borda na Forma que estiver sobre o Mouse no momento em que estiver selecionado um novo objeto a ser inserido no Diagrama. * * @param limpa apagar. * @param el elementar um cujo o mouse está ou estava sobre . * */ public void ProcessaOverDraw(boolean limpa, Elementar el) { int x = 4; int y = 4; if (limpa) { if (overDraw != null) { overDraw.setOverMe(false); Rectangle rec = AlmentarRetangulo(overDraw.getBounds(), x, y); overDraw.InvalidateArea(rec); overDraw = null; } return; } if (el == null && overDraw != null) { overDraw.setOverMe(false); Rectangle rec = AlmentarRetangulo(overDraw.getBounds(), x, y); overDraw.InvalidateArea(rec); overDraw = null; } else if (el != null && el instanceof FormaElementar && el != overDraw) { if (overDraw != null) { overDraw.setOverMe(false); Rectangle rec = AlmentarRetangulo(overDraw.getBounds(), x, y); overDraw.InvalidateArea(rec); } overDraw = (FormaElementar) el; overDraw.setOverMe(true); Rectangle rec = AlmentarRetangulo(overDraw.getBounds(), x, y); overDraw.InvalidateArea(rec); } } // <editor-fold defaultstate="collapsed" desc="Trata Elementar"> /** * Verifica que componente está na posição "ponto" obedecendo a ordem z [melhoria: 16/05/2014] Dá preferência ao obj selecionado, independentemente da ordem z para fins de melhor seleção e movimentação com o mouse. * * @param ponto = local. Poder ser a posição x e y do mouse * @return o Componente. */ public Elementar CaptureFromPoint(Point ponto) { Elementar res = getSelecionado(); if (res != null) { res = res.IsMeOrMine(ponto); if (res != null) { return res; } } for (Elementar el : subItens) { res = el.IsMeOrMine(ponto); if (res != null) { return res; } } return null; } public Elementar CaptureFromPoint(Elementar nor, Point ponto) { Elementar res = null; for (Elementar el : subItens) { res = el.IsMeOrMine(ponto, nor); if (res != null) { return res; } } return null; } public Forma CaptureBaseFromPoint(Elementar nor, Point ponto) { Elementar res = null; for (Elementar el : subItens) { res = el.IsMeOrMineBase(ponto, nor); if (res != null) { return (Forma) res; } } return null; } private transient Elementar elementarSobMouse = null; /** * @return the elementarSobMouse */ public Elementar getElementarSobMouse() { return elementarSobMouse; } /** * @param elementarSobMouse the elementarSobMouse to set */ public void setElementarSobMouse(Elementar elementarSobMouse) { this.elementarSobMouse = elementarSobMouse; } // </editor-fold> Point DiagramaDownPos = new Point(0, 0); boolean isMouseDown = false; public void mouseReleased(MouseEvent e) { e = tradutorZoom(e); if (isMouseDown) { isMouseDown = false; Rectangle recsel = master.getMultSel().getBounds(); boolean combine = (isShiftDown() || isControlDown()); if (!combine) { ClearSelect(); } final Point p = e.getPoint(); master.FinishMultiSel(); subItens.stream().filter((c) -> (c instanceof FormaElementar)).map((c) -> (FormaElementar) c).filter((item) -> (item.IntersectPath(recsel))) .sorted((p1, p2) -> Double.compare(Utilidades.distance(p1.getLocation(), p), Utilidades.distance(p2.getLocation(), p))) .forEach((item) -> { DiagramaDoSelecao(item, true, true); }); //tmp.Posicione(getSelecionado()); repaint(Utilidades.Grow(recsel, 2, 2, 0)); } if (draging && (elementarSobMouse != null)) { elementarSobMouse.mouseReleased(e); superAncorador.Posicione(getSelecionado()); } draging = false; } public void mouseWheelMoved(MouseWheelEvent e) { if (e.isControlDown()) { if (e.getWheelRotation() < 0) { getEditor().ZoomMais(); } else { getEditor().ZoomMenos(); } e.consume(); } } // public void EndPoupup() { // JOptionPane.showMessageDialog(null, "FIM", "FIM2", JOptionPane.CANCEL_OPTION); // } // </editor-fold> public transient boolean IsStopEvents = false; public transient boolean isCarregando = false; protected transient boolean isLoadCreate = false; private boolean mudou = false; /** * Armazena o ID */ protected int TotalID = 0; public Point ScrPosicao = new Point(0, 0); /** * Gera um ID único para cada elemetar criado pelo modelo. * * @return novo ID */ public int getElementarID() { return ++TotalID; } public boolean getMudou() { return mudou; } public void setMudou(boolean value) { if (mudou != value) { mudou = value; if (!value) { PerformInspector(); } getEditor().getShowDiagramas().repaint(); } } // <editor-fold defaultstate="collapsed" desc="Seleção"> /** * Esconde ou mostra os pontos de uma Componente * * @param esconde true: esconde, false: mostra. */ public void HidePontosOnSelecao(boolean esconde) { for (FormaElementar item : itensSelecionados) { item.HidePontos(esconde); } } /** * Seleciona um componente * * @param item * @return selecionou? */ public boolean DiagramaDoSelecao(FormaElementar item) { return DiagramaDoSelecao(item, false, false); } /** * Seleciona um componente * * @param item * @param ehmouse "É mouse": true: processa combinações de teclado para seleção múltipla (multiseleção). * @param ForcarMultSel * @return */ public boolean DiagramaDoSelecao(FormaElementar item, boolean ehmouse, boolean ForcarMultSel) { if (item == null) { ClearSelect(); return false; } if (!item.isSelecionavel()) { master.getControler().makeEnableComands(); return false; } boolean combine = ((isShiftDown() || isControlDown()) && ehmouse) || ForcarMultSel; if (itensSelecionados.indexOf(item) == -1) { if (combine) { AddSelect(item); } else { if (itensSelecionados.size() > 0) { ClearSelect(false); } AddSelect(item); } PerformInspector(); master.getControler().makeEnableComands(); superAncorador.Posicione(getSelecionado()); return true; } else if ((combine) && (itensSelecionados.size() > 1)) { RemoveSelect(item); PerformInspector(); //master.getControler().makeEnableComands(); superAncorador.Posicione(getSelecionado()); return false; } else { //PerformInspector(); master.getControler().makeEnableComands(); superAncorador.Posicione(getSelecionado()); return true; } } private void PontosCor(FormaElementar item) { PontosCor(item, false); } private void PontosCor(FormaElementar item, boolean verde) { item.DoPontoCor(verde); } private void AddSelect(FormaElementar item) { itensSelecionados.add(item); if (itensSelecionados.size() > 1) { PontosCor(item, true); } item.setSelecionado(true); } public void PromoveToFirstSelect(FormaElementar item) { int idx = itensSelecionados.indexOf(item); if (idx > 0) { PontosCor(itensSelecionados.get(0), true); itensSelecionados.remove(item); itensSelecionados.add(0, item); PontosCor(item); } } private void RemoveSelect(FormaElementar item) { if (itensSelecionados.indexOf(item) == -1) { return; } itensSelecionados.remove(item); PontosCor(item); item.setSelecionado(false); //if (itensSelecionados.size() == 1) { PontosCor(itensSelecionados.get(0)); //} } /** * Limpa/des-seleciona todos os selecionados. */ public void ClearSelect() { ClearSelect(true); } /** * Limpa/des-seleciona todos os selecionados. Redesenha o Inspector * * @param performInsp */ public void ClearSelect(boolean performInsp) { itensSelecionados.forEach(item -> { PontosCor(item); item.setSelecionado(false); }); itensSelecionados.clear(); if (performInsp) { master.getControler().makeEnableComands(); PerformInspector(); } superAncorador.SetVisible(false); } public boolean TemSelecionado() { return itensSelecionados.size() > 0; } public FormaElementar getSelecionado() { if (TemSelecionado()) { return itensSelecionados.get(0); } return null; } public void setSelecionado(FormaElementar sel) { DiagramaDoSelecao(sel, false, false); } // </editor-fold> public void ReciveProcessMove(FormaElementar nor, int x, int y) { itensSelecionados.stream().filter(item -> item != nor).forEach(item -> item.DoMove(x, y)); // for (FormaElementar item : itensSelecionados) { // if (item == nor) { // continue; // } // item.DoMove(x, y); // } } //<editor-fold defaultstate="collapsed" desc="Teclas"> /** * @return the shiftDown */ public boolean isShiftDown() { return master.isShiftDown(); } /** * @return the altDown */ public boolean isAltDown() { return master.isAltDown(); } /** * @return the controlDown */ public boolean isControlDown() { return master.isControlDown(); } // </editor-fold> public void DoFormaResize(Rectangle ret) { if (ret.x == 0 && ret.y == 0 && ret.width == 0 && ret.height == 0) { return; } itensSelecionados.stream().filter((de) -> (de instanceof Forma)).map((de) -> (Forma) de).forEach((item) -> { item.ReciveFormaResize(ret); }); repaint(); } public void DoBaseReenquadreReposicione() { itensSelecionados.stream().filter((item) -> (!item.Reenquadre())).forEach((item) -> { item.Reposicione(); }); } /** * Recebe as teclas do Editor. * * @param e */ public void ProcesseTeclas(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { setComando(null); return; } if (e.getKeyCode() == KeyEvent.VK_ENTER) { InspectorItemBase ppr = getEditor().getInspectorEditor().FindByProperty("setTexto"); if (ppr != null) { if (getEditor().getInspectorEditor().getSelecionado() == ppr) { getEditor().getInspectorEditor().PerformSelect(null); } getEditor().getInspectorEditor().PerformSelect(ppr); if (ppr instanceof InspectorItemExtender) { ((InspectorItemExtender) ppr).ExternalRun(); } } return; } if (itensSelecionados.isEmpty()) { return; } FormaElementar item = itensSelecionados.get(0); int x = 0, y = 0; int inc = 3; if (e.isControlDown()) { inc = 1; } switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: x = -inc; y = 0; break; case KeyEvent.VK_RIGHT: x = inc; y = 0; break; case KeyEvent.VK_UP: x = 0; y = -inc; break; case KeyEvent.VK_DOWN: x = 0; y = inc; break; } if (item.isAncorado()) { //HidePontosOnSelecao(false); e.consume(); } else if (x != 0 || y != 0) { if (e.isShiftDown() && item instanceof Forma) { Rectangle rec = new Rectangle(0, 0, -x, -y); ((Forma) item).DoFormaResize(rec); } else { item.DoRaiseMove(x, y); } superAncorador.Posicione(item); DoBaseReenquadreReposicione(); HidePontosOnSelecao(false); PerformInspector(); e.consume(); } } /** * Recebe as comandos na forma de teclas Editor. * * @param k */ public void ProcesseTeclas(int k) { if (itensSelecionados.isEmpty()) { return; } FormaElementar item = itensSelecionados.get(0); if (item.isAncorado()) { return; } int x = 0, y = 0; int inc = (isControlDown()) ? 1 : 3; switch (k) { case KeyEvent.VK_LEFT: x = -inc; y = 0; break; case KeyEvent.VK_RIGHT: x = inc; y = 0; break; case KeyEvent.VK_UP: x = 0; y = -inc; break; case KeyEvent.VK_DOWN: x = 0; y = inc; break; } if (x != 0 || y != 0) { if (isShiftDown() && item instanceof Forma) { Rectangle rec = new Rectangle(0, 0, -x, -y); ((Forma) item).DoFormaResize(rec); } else { item.DoRaiseMove(x, y); } superAncorador.Posicione(item); DoBaseReenquadreReposicione(); HidePontosOnSelecao(false); } master.requestFocus(); PerformInspector(); } public boolean SelecioneProximo() { if (itensSelecionados.isEmpty()) { return false; } FormaElementar item = itensSelecionados.get(0); if (itensSelecionados.size() == 1 && ListaDeItens.size() > 1) { int idxAtual = ListaDeItens.indexOf(item); int idx = idxAtual; while (true) { idx++; if (idx >= ListaDeItens.size()) { idx = 0; } if (idx == idxAtual) { break; } item = ListaDeItens.get(idx); if (item.isSelecionavel()) { DiagramaDoSelecao(item, false, false); return true; } } } return false; } public boolean SelecioneAnterior() { if (itensSelecionados.isEmpty()) { return false; } FormaElementar item = itensSelecionados.get(0); if (itensSelecionados.size() == 1 && ListaDeItens.size() > 1) { int idxAtual = ListaDeItens.indexOf(item); int idx = idxAtual; while (true) { idx--; if (idx < 0) { idx = ListaDeItens.size() - 1; } if (idx == idxAtual) { break; } item = ListaDeItens.get(idx); if (item.isSelecionavel()) { DiagramaDoSelecao(item, false, false); return true; } } } return false; } public void SelecioneTodos() { ClearSelect(false); for (FormaElementar it : getListaDeItens()) { DiagramaDoSelecao(it, false, true); } PerformInspector(); } /** * Adiciona um componente ao Diagrama. * * @param aThis */ public final void Add(FormaElementar aThis) { subItens.add(aThis); ListaDeItens.add(aThis); } public boolean IsMultSelecionado() { return itensSelecionados.size() > 1; } private boolean Remove(FormaElementar item) { if (!item.isCanBeDeleted()) { return item.AskToDelete(); } ListaDeItens.remove(item); subItens.remove(item); item.Destroy(); return true; } public boolean Remove(FormaElementar item, boolean removeSel) { if (Remove(item)) { if (removeSel) { itensSelecionados.remove(item); } return true; } return false; } public boolean deleteSelecao() { if (TemSelecionado()) { itensSelecionados.stream().forEach((el) -> { Remove(el); }); itensSelecionados.clear(); DoMuda(null); repaint(); master.getControler().makeEnableComands(); return true; } return false; } // <editor-fold defaultstate="collapsed" desc="Comando"> private transient Controler.Comandos comando = null; protected void setComando(Controler.Comandos cmd) { comando = cmd; if (cmd == null) { master.NoAction(); setCursor(new Cursor((Cursor.DEFAULT_CURSOR))); ProcessaOverDraw(true, null); } } public Controler.Comandos getComando() { return comando; } public void DoAction(ActionEvent ev) { if (ev.getActionCommand() == null || ev.getActionCommand().isEmpty()) { setComando(null); return; } try { Controler.Comandos cmd = Controler.Comandos.valueOf(ev.getActionCommand()); if (comando != cmd) { cliq1 = null; cliq2 = null; } setComando(cmd); } catch (Exception e) { setComando(null); } } public class clickForma { private final FormaElementar forma; private final Point ponto; public clickForma(FormaElementar forma, Point ponto) { this.forma = forma; this.ponto = ponto; } public FormaElementar getForma() { return forma; } public Point getPonto() { return ponto; } } /** * Usada para criar objetos na forma padrão de forma externa * * @param cmd * @param posi * @return novo objeto/objeto criado */ public FormaElementar ExternalRealiseComando(Controler.Comandos cmd, Point posi) { Controler.Comandos c = getComando(); setComando(cmd); FormaElementar res = RealiseComando(posi); setComando(c); return res; } protected transient clickForma cliq1 = null, cliq2 = null; protected FormaElementar RealiseComando(Point posi) { //ClearSelect(false); FormaElementar resu = null; //Point tmpPt; Controler.Comandos com = comando; Elementar res = null; switch (com) { case cmdDesenhador: Desenhador dz = new Desenhador(this); dz.SetBounds(posi.x, posi.y, 250, 150); dz.Reenquadre(); resu = dz; break; case cmdLegenda: Legenda leg = new Legenda(this); leg.SetBounds(posi.x, posi.y, 150, 45); leg.Reenquadre(); resu = leg; break; case cmdTexto: res = CaptureFromPoint(posi); Texto Tx = new Texto(this, "Texto"); if (res instanceof SuperLinha) { Tx.SetBounds(posi.x, posi.y, 100, 18); Tx.setAlinhamento(AlinhamentoTexto.alEsquerda); Tx.setTipo(TipoTexto.tpEmBranco); Tx.setCentrarVertical(false); ((SuperLinha) res).setTag(Tx); } else { Tx.SetBounds(posi.x, posi.y, 150, 36); Tx.Reenquadre(); } resu = Tx; break; case cmdApagar: res = CaptureFromPoint(posi); if (res instanceof FormaElementar) { resu = (FormaElementar) res; ClearSelect(); setSelecionado(resu); deleteSelecao(); } resu = null; } cliq1 = null; cliq2 = null; if (!master.isControlDown()) { setComando(null); } else { setComando(com); } if (resu != null) { resu.BringToFront(); } return resu; } // </editor-fold> /** * Redesenha o inspector com o objeto selecionado. É chamado também no método setMuda(true). */ public void PerformInspector() { if (!itensSelecionados.isEmpty()) { getEditor().PerformInspectorFor(itensSelecionados.get(0)); } else { getEditor().PerformInspectorFor(infoDiagrama); } } /** * Redesenha o inspector com o objeto selecionado. * * @param force = limpa as propriedades previamente capturadas de forma que a chamada ao inspector force uma recarga. */ public void PerformInspector(boolean force) { if (force) { getEditor().getInspectorEditor().ForceFullOnCarregue(); } PerformInspector(); } /** * Este médodo é usado quando precisa-se usar o inspector para editar propriedade de sub componete * * @param ed: componete principal em edição. * @param bj: o java não tem passagem por referencia - boxing da "propriedade" em edição * @return: o sub componente (se for o caso). */ public Object processeEdicaoSubItem(FormaElementar ed, BoxingJava bj) { return ed; } public boolean AceitaEdicao(InspectorProperty prop, String valor) { FormaElementar param; if (itensSelecionados.isEmpty()) { param = infoDiagrama; } else { param = itensSelecionados.get(0); } Object ed = param; String P = prop.property; //caso de edição de sub componente. Exemplo: EntidadeAssociativa.Relacao if (P.indexOf('.') > 0) { util.BoxingJava bj = new util.BoxingJava(P); ed = processeEdicaoSubItem(param, bj); P = bj.Str; } final String propriedade = P; final Class[] par = new Class[1]; final Object[] vl = new Object[1]; try { switch (prop.tipo) { case tpBooleano: par[0] = Boolean.TYPE; vl[0] = Boolean.parseBoolean(valor); break; case tpCor: par[0] = Color.class; vl[0] = util.Utilidades.StringToColor(valor); break; case tpMenu: par[0] = Integer.TYPE; int p = Integer.parseInt(valor); vl[0] = p; break; case tpNumero: par[0] = Integer.TYPE; final int tmp = Integer.parseInt(valor); vl[0] = tmp; final String[] pprtMv = {"setLeft", "setTop", "setWidth", "setHeight"}; if (Arrays.asList(pprtMv).indexOf(propriedade) > -1) { if (ed instanceof Forma) { IsStopEvents = true; itensSelecionados.stream().filter(e -> e.getClass().equals(param.getClass())).map(f -> (Forma) f).forEach(Ed -> { Rectangle ret; if ((propriedade.equals(pprtMv[0]))) { ret = new Rectangle(Ed.getLeft() - tmp, 0, 0, 0); } else if (propriedade.equals(pprtMv[1])) { ret = new Rectangle(0, Ed.getTop() - tmp, 0, 0); } else if (propriedade.equals(pprtMv[2])) { ret = new Rectangle(0, 0, Ed.getWidth() - tmp, 0); } else { ret = new Rectangle(0, 0, 0, Ed.getHeight() - tmp); } //Ed.DoFormaResize(ret); Ed.ReciveFormaResize(ret); Ed.DoRaizeReenquadreReposicione(); //DoMuda(Ed); }); IsStopEvents = false; DoMuda(param); return true; } } break; default: par[0] = String.class; vl[0] = valor; } final String[] multi = {"setForeColor", "setTipoAtributo"}; //quais propriedades proderão ser editadas em cojunto if (Arrays.asList(multi).indexOf(propriedade) == -1 || ((ed instanceof Forma) && ((Forma) ed).getPrincipal() != null)) { Class cl = ed.getClass(); Method mthd = cl.getMethod(propriedade, par); mthd.invoke(ed, vl); DoMuda(param); } else { //List<FormaElementar> lst = itensSelecionados.stream().filter(e -> e.getClass().equals(param.getClass())).collect(Collectors.toList()); final List<FormaElementar> lst; final String[] multi_any = {"setForeColor"}; //de qualquer classe ? (sim, neste array). ELSE: mesma classe do objeto selecionado principal if (Arrays.asList(multi_any).indexOf(propriedade) > -1) { lst = itensSelecionados.stream().collect(Collectors.toList()); } else { lst = itensSelecionados.stream().filter(e -> e.getClass().equals(param.getClass())).collect(Collectors.toList()); } IsStopEvents = true; for (FormaElementar Ed : lst) { Class cl = Ed.getClass(); Method mthd = cl.getMethod(propriedade, par); mthd.invoke(Ed, vl); } IsStopEvents = false; DoMuda(param); } } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { util.BrLogger.Logger("ERROR_SET_PROPERTY", e.getMessage()); IsStopEvents = false; superAncorador.InvalidateArea(); return false; } superAncorador.InvalidateArea(); return true; } /** * Usado para os métodos copiarFormatacao. * * @param param O que está sendo colado * @param prop uma de suas propriedades * @param valor novo valor. * @return */ public boolean ColeFormatacao(FormaElementar param, InspectorProperty prop, String valor) { Object ed = param; String propriedade = prop.property; //caso de edição de sub componente. Exemplo: EntidadeAssociativa.Relacao if (propriedade.indexOf('.') > 0) { util.BoxingJava bj = new util.BoxingJava(propriedade); ed = processeEdicaoSubItem(param, bj); propriedade = bj.Str; } Class[] par = new Class[1]; Object[] vl = new Object[1]; try { switch (prop.tipo) { case tpBooleano: par[0] = Boolean.TYPE; vl[0] = Boolean.parseBoolean(valor); break; case tpCor: par[0] = Color.class; vl[0] = util.Utilidades.StringToColor(valor); //new Color(Integer.parseInt(valor)); break; case tpMenu: par[0] = Integer.TYPE; int p = Integer.parseInt(valor); vl[0] = p; break; case tpNumero: par[0] = Integer.TYPE; int tmp = Integer.parseInt(valor); vl[0] = tmp; String[] pprtMv = {"setLeft", "setTop", "setWidth", "setHeight"}; if (Arrays.asList(pprtMv).indexOf(propriedade) > -1) { Rectangle ret; if (ed instanceof Forma) { Forma Ed = (Forma) ed; if ((propriedade.equals(pprtMv[0]))) { ret = new Rectangle(Ed.getLeft() - tmp, 0, 0, 0); } else if (propriedade.equals(pprtMv[1])) { ret = new Rectangle(0, Ed.getTop() - tmp, 0, 0); } else if (propriedade.equals(pprtMv[2])) { ret = new Rectangle(0, 0, Ed.getWidth() - tmp, 0); } else { ret = new Rectangle(0, 0, 0, Ed.getHeight() - tmp); } Ed.DoFormaResize(ret); Ed.DoRaizeReenquadreReposicione(); DoMuda(Ed); return true; } } break; default: par[0] = String.class; vl[0] = valor; } Class cl = ed.getClass(); Method mthd = cl.getMethod(propriedade, par); mthd.invoke(ed, vl); DoMuda(param); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { util.BrLogger.Logger("ERROR_SET_PROPERTY", e.getMessage()); return false; } return true; } /** * Com base nos nomes dos objetos traduzidos nos arq. de confg. nomeia os objetos no ato de criação. * * @param padrao nome dado por mim * @return nome traduzido/configurado pelo usuário. */ public final String Nomeie(String padrao) { String txt = Editor.fromConfiguracao.getValor("diagrama." + padrao + ".nome"); int res = 1; ArrayList<String> txts = new ArrayList<>(); ListaDeItens.stream().filter((el) -> (el instanceof Forma)).map(el -> (Forma) el).forEach(el -> el.EscrevaTexto(txts)); while (txts.indexOf(txt + "_" + res) != -1) { res++; } return txt + "_" + res; } /** * Procura um artefato pelo ID * * @param id * @return encontrado */ public FormaElementar FindByID(int id) { for (FormaElementar f : getListaDeItens()) { if (f.getID() == id) { return f; } } return null; } // Nunca usado! 20/09/2014 // public void CheckLigConsistencia(Forma sender, Forma emQuem, Linha por) { // } public void DoMuda(FormaElementar who) { if (isLoadCreate || isCarregando) { return; } setMudou(true); try { master.DoDiagramaMuda(); } catch (Exception e) { util.BrLogger.Logger("ERROR_DIAGRAMA_MUDA", e.getMessage()); } // if (who != null && TemSelecionado()) { // if (who != itensSelecionados.get(0)) return; // } PerformInspector(); } //<editor-fold defaultstate="collapsed" desc="Save Load"> /** * Gera uma Stream a partir de um modelo * * @param othis * @return */ public synchronized static ByteArrayOutputStream SaveToStream(Diagrama othis) { try { ByteArrayOutputStream ba = new ByteArrayOutputStream(); try (ObjectOutput out = new ObjectOutputStream(ba)) { out.writeObject(othis); } othis.tick(); return ba; } catch (IOException iOException) { util.BrLogger.Logger("ERROR_DIAGRAMA_SAVELOAD_STREAM", iOException.getMessage()); return null; } } public final static String nodePrincipal = "DIAGRAMA"; private static TipoDeDiagrama GetTipoOnXml(Document doc) { try { NodeList nodeLst = doc.getElementsByTagName(nodePrincipal); Element prin = (Element) nodeLst.item(0); String tp = prin.getAttribute("TIPO"); return TipoDeDiagrama.valueOf(tp); } catch (Exception e) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD_TIPO_XML", e.getMessage()); return null; } } /** * Gera um diagrama novo a partir de uma Stream * * @param ba * @return */ public synchronized static Diagrama LoadFromStream(ByteArrayOutputStream ba) { try { byte[] bytes = ba.toByteArray(); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); //in = new ObjectInputStream(new ByteArrayInputStream(bytes)); Diagrama res = (Diagrama) in.readObject(); in.close(); return res; } catch (ClassNotFoundException | IOException e) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD", e.getMessage()); return null; } } /** * Gera um diagrama novo a partir de um Arquivo * * @param arq * @param master * @return */ public synchronized static Diagrama LoadFromFile(File arq, Editor master) { if (arq == null || master.IsOpen(arq)) { return null; } Diagrama res = null; String onome = arq.getName(); if (util.Arquivo.IsbrM3(arq)) { onome = onome.substring(0, onome.length() - util.Arquivo.brM3.length() - 1); } else { onome = onome.substring(0, onome.length() - util.Arquivo.xml.length() - 1); } if (util.Arquivo.IsbrM3(arq)) { try { FileInputStream fi = new FileInputStream(arq); try (ObjectInput in = new ObjectInputStream(fi)) { GuardaPadraoBrM seguranca = (GuardaPadraoBrM) in.readObject(); in.close(); res = seguranca.getDiagrama(); res.setMaster(master); } //Recria o UID para se ter a certeza de que ele é único, não repetido por uma eventual cópaia do arquivo. res.ReGeraUniversalUnicID(); res.setArquivo(arq.getAbsolutePath()); master.addLastOpened(arq.getAbsolutePath()); res.SetNome(onome); return res; } catch (NullPointerException | IOException | ClassNotFoundException iOException) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD_FILE_BRM", iOException.getMessage()); return null; } } else { Document doc = util.XMLGenerate.LoadDocument(arq); if (doc == null) { return null; } TipoDeDiagrama tp = GetTipoOnXml(doc); res = master.Novo(tp); if (!res.LoadFromXML(doc, false)) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD_FILE_XML", "[IS BRM XML?]"); } //Recria o UID para se ter a certeza de que ele é único, não repetido por uma eventual cópaia do arquivo. res.ReGeraUniversalUnicID(); res.setArquivo(arq.getAbsolutePath()); res.SetNome(onome); master.addLastOpened(arq.getAbsolutePath()); return res; } } /** * Gera um diagrama novo a partir de um GuardaPadraoBrM * * @param seguranca * @param master * @return */ public synchronized static Diagrama LoadFromBrm(GuardaPadraoBrM seguranca, Editor master) { if (seguranca == null) { return null; } Diagrama res = seguranca.getDiagrama(); res.setMaster(master); //Recria o UID para se ter a certeza de que ele é único, não repetido por uma eventual cópaia do arquivo. res.ReGeraUniversalUnicID(); res.setArquivo(""); //O nome está aramzendo no TAG para facilitar a identificação. res.SetNome(seguranca.Tag); return res; } public boolean LoadFromXML(Document doc, boolean colando) { HashMap<Element, FormaElementar> link = new HashMap<>(); try { //<editor-fold defaultstate="collapsed" desc="Remover espaços - http://stackoverflow.com/questions/978810/how-to-strip-whitespace-only-text-nodes-from-a-dom-before-serialization"> XPathFactory xpathFactory = XPathFactory.newInstance(); // XPath to find empty text nodes. XPathExpression xpathExp = xpathFactory.newXPath().compile( "//text()[normalize-space(.) = '']"); NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(doc, XPathConstants.NODESET); // Remove each empty text node from document. for (int i = 0; i < emptyTextNodes.getLength(); i++) { Node emptyTextNode = emptyTextNodes.item(i); emptyTextNode.getParentNode().removeChild(emptyTextNode); } //</editor-fold> NodeList nodeLst = doc.getElementsByTagName(Diagrama.nodePrincipal); Node mer = nodeLst.item(0); nodeLst = mer.getChildNodes(); if (colando) { ClearSelect(true); ((InfoDiagrama) infoDiagrama).setDiagramaOldUniversalUnicID(String.valueOf(((Element) mer).getAttribute("UniversalUnicID"))); } this.isLoadCreate = true; this.isCarregando = true; int tl = 0; int maxID = 0; for (int s = 0; s < nodeLst.getLength(); s++) { Node fstNode = nodeLst.item(s); if (fstNode.getNodeType() == Node.ELEMENT_NODE) { Element fstElmnt = (Element) fstNode; FormaElementar res = runCriadorFromXml(fstElmnt, colando); if (res == null) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD", "Lixo ou objeto alienígena encontrado: " + fstElmnt.toString() + " - não é possível colar este objeto", "[]"); continue; } tl++; if (!colando) { maxID = Math.max(maxID, res.getID()); } link.put(fstElmnt, res); maxID = OnLoadingXMLitem(res, fstElmnt, colando, maxID, link); } } if (!colando) { TotalID = maxID; } this.isLoadCreate = false; link.keySet().stream().forEach((el) -> { FormaElementar proc = link.get(el); proc.CommitXML(el, link); }); this.isCarregando = false; if (colando) { if (((Element) mer).hasAttribute("FIRST_SEL")) { ReestrutureSelecao(((Element) mer).getAttribute("FIRST_SEL"), link); } } if (tl > 0 && colando) { DoMuda(null); } PerformInspector(); } catch (Exception e) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD", e.getMessage()); this.isLoadCreate = false; this.isCarregando = false; return false; } repaint(); return true; } //private boolean naoMostre = false; protected int OnLoadingXMLitem(FormaElementar res, Element fstElmnt, boolean colando, int maxID, HashMap<Element, FormaElementar> link) { return maxID; } protected void ReestrutureSelecao(String oid, HashMap<Element, FormaElementar> link) { FormaElementar ja = null; for (Element el : link.keySet()) { FormaElementar proc = link.get(el); if (ja == null && el.hasAttribute("ID") && el.getAttribute("ID").equals(oid)) { ja = proc; } DiagramaDoSelecao(proc, false, true); } if (ja != null) { PromoveToFirstSelect(ja); } } protected FormaElementar ReflectionObj(Class classeDoObj) { Class[] argsConstr = new Class[]{Diagrama.class}; Object[] omodelo = new Object[]{this}; Constructor construtor; FormaElementar res; try { construtor = classeDoObj.getConstructor(argsConstr); try { res = (FormaElementar) construtor.newInstance(omodelo); return res; } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD_REFLECTION_CREATE_OBJ", e.getMessage()); } } catch (NoSuchMethodException e) { util.BrLogger.Logger("ERROR_DIAGRAMA_LOAD_REFLECTION_CONSTRUCTOR", e.getMessage()); } return null; } protected FormaElementar runCriadorFromXml(Element xml, boolean colando) { int classe = xml.getNodeName().hashCode(); if (classe == InfoDiagrama.class.getSimpleName().hashCode()) { if (!colando) { LoadFromXML(this.infoDiagrama, xml, false); } return this.infoDiagrama; } final Class[] classes = getCassesDoDiagrama(); for (Class cl : classes) { if (cl.getSimpleName().hashCode() == classe) { FormaElementar res = ReflectionObj(cl); if (res != null) { LoadFromXML(res, xml, colando); } return res; } } return null; } protected void LoadFromXML(FormaElementar obj, Element xml, boolean colando) { try { obj.LoadFromXML(xml, colando); } catch (Exception e) { util.BrLogger.Logger("ERROR_OBJECT_LOAD", Integer.toString(obj.getID()) + " - " + obj.getClass().getSimpleName(), e.getMessage()); } } public static String SaveToXml(Diagrama othis, boolean justSel) { return XMLGenerate.GeraXMLFrom(othis, justSel); } public boolean Salvar() { File arq = util.Dialogos.ShowDlgSaveDiagrama(master.getRootPane(), this); if (arq == null) { return false; } return Salvar(arq, true); } public boolean Salvar(String fileName) { if ("".equals(fileName) || fileName == null) { return Salvar(); } File arq = new File(fileName); return Salvar(arq, false); } public boolean Salvar(File fileName, boolean pergunta) { if (fileName.exists() && pergunta) { if (util.Dialogos.ShowMessageConfirm(master.getRootPane(), Editor.fromConfiguracao.getValor("Controler.MSG_QUESTION_REWRITE")) != JOptionPane.YES_OPTION) { return false; } } String txt = getNome(); String onome = fileName.getName(); versaoA = Diagrama.VERSAO_A; versaoB = Diagrama.VERSAO_B; versaoC = Diagrama.VERSAO_C; if (util.Arquivo.IsbrM3(fileName)) { onome = onome.substring(0, onome.length() - util.Arquivo.brM3.length() - 1); } else { onome = onome.substring(0, onome.length() - util.Arquivo.xml.length() - 1); } setNome(onome); if (util.Arquivo.IsbrM3(fileName)) { try { FileOutputStream fo = new FileOutputStream(fileName); try (ObjectOutput out = new ObjectOutputStream(fo)) { //não guardar o diretório onde se encontra na origem (segurança!!?? Inútil guardar.) this.setArquivo(""); //out.writeObject(this); GuardaPadraoBrM seg = new GuardaPadraoBrM(this); seg.versaoDiagrama = versaoA + "." + versaoB + "." + versaoC; out.writeObject(seg); } this.setArquivo(fileName.getAbsolutePath()); master.addLastOpened(fileName.getAbsolutePath()); this.setMudou(false); master.DoAutoSaveCompleto(); PerformInspector(); return true; } catch (IOException iOException) { util.BrLogger.Logger("ERROR_DIAGRAMA_SAVE_BRM", iOException.getMessage()); setNome(txt); return false; } } else { try { StringWriter ou = XMLGenerate.GeraXMLtoSaveFrom(this, false); try (BufferedWriter out = new BufferedWriter(new FileWriter(fileName))) { out.write(ou.getBuffer().toString()); this.setArquivo(fileName.getAbsolutePath()); master.addLastOpened(fileName.getAbsolutePath()); this.setMudou(false); master.DoAutoSaveCompleto(); PerformInspector(); return true; } } catch (IOException iOException) { util.BrLogger.Logger("ERROR_DIAGRAMA_SAVE_XML", iOException.getMessage()); setNome(txt); return false; } } } public boolean AutoSalvar(ArrayList<byte[]> as) { versaoA = Diagrama.VERSAO_A; versaoB = Diagrama.VERSAO_B; versaoC = Diagrama.VERSAO_C; try { ByteArrayOutputStream fo = new ByteArrayOutputStream(); try (ObjectOutput out = new ObjectOutputStream(fo)) { GuardaPadraoBrM seg = new GuardaPadraoBrM(this); seg.versaoDiagrama = versaoA + "." + versaoB + "." + versaoC; seg.Tag = this.getNome(); out.writeObject(seg); } as.add(fo.toByteArray()); return true; } catch (IOException iOException) { util.BrLogger.Logger("ERROR_DIAGRAMA_AUTOSAVE_MEM", iOException.getMessage()); return false; } } //</editor-fold> @Override public void lostOwnership(Clipboard clipboard, Transferable contents) { //throw new UnsupportedOperationException("Not supported yet."); } public void doCopy() { String res = Diagrama.SaveToXml(this, true); StringSelection vai = new StringSelection(res); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents(vai, this); } public void doCopy(BufferedImage img) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); util.TransferableImage trans = new util.TransferableImage(img); clipboard.setContents(trans, this); } public void doPaste() { String txt = getClipboardContents(); if (!"".equals(txt)) { Document doc = util.XMLGenerate.LoadDocument(txt); processePaste(doc); } else { BufferedImage img = getClipboardContentsImage(); if (img != null) { int x = getEditor().getMargem() >= ScrPosicao.x ? 4 : ScrPosicao.x + 4 - getEditor().getMargem(); int y = getEditor().getMargem() >= ScrPosicao.y ? 4 : ScrPosicao.y + 4 - getEditor().getMargem(); Point p = tradutorZoom(new Point(x, y)); x = p.x; y = p.y; FormaElementar xres = ExternalRealiseComando(Controler.Comandos.cmdDesenhador, p); Desenhador de = (Desenhador) xres; de.setTipoImg(); de.setImagem(img); de.SetBounds(x, y, img.getWidth(), img.getHeight()); de.InvalidateArea(); DiagramaDoSelecao(de, false, false); DoMuda(null); PerformInspector(); } } } public boolean doPaste(String txt) { if (!"".equals(txt)) { Document doc = util.XMLGenerate.LoadDocument(txt); return (processePaste(doc)); } return false; } private boolean processePaste(Document doc) { if (doc != null) { boolean res = LoadFromXML(doc, true); if (res) { Point p = getPontoMenorSelecionado(); Point q = new Point((getEditor().getMargem() >= ScrPosicao.x ? ScrPosicao.x : ScrPosicao.x - getEditor().getMargem()), (getEditor().getMargem() >= ScrPosicao.y ? ScrPosicao.y : ScrPosicao.y - getEditor().getMargem())); q = tradutorZoom(q); final int x = p.x - q.x; final int y = p.y - q.y; ArrayList<FormaElementar> lst = new ArrayList<>(); getItensSelecionados().stream().forEach(f -> lst.add(f)); setSelecionado(null); lst.stream().filter(f -> f instanceof Forma).forEach(fe -> { fe.HidePontos(true); fe.DoMove(-x + 2 * fe.distSelecao, -y + 2 * fe.distSelecao); fe.Reposicione(); fe.HidePontos(false); }); lst.stream().filter(f -> f instanceof SuperLinha).map(sl -> (SuperLinha) sl).forEach(fe -> { fe.HidePontos(true); final int a = -x + 2 * fe.distSelecao; final int b = -y + 2 * fe.distSelecao; if (fe.getPontaA().getEm() == null && fe.getPontaB().getEm() == null) { fe.DoMove(a, b); } else { if (fe.getPontaA().getEm() != null && fe.getPontaB().getEm() == null) { fe.getPontos().stream().filter(pt -> pt != fe.getPontaA()).forEach(pt -> pt.DoMove(a, b)); } if (fe.getPontaB().getEm() != null && fe.getPontaA().getEm() == null) { fe.getPontos().stream().filter(pt -> pt != fe.getPontaB()).forEach(pt -> pt.DoMove(a, b)); } } fe.Reposicione(); fe.HidePontos(false); }); //Seleciona novamente. if (!lst.isEmpty()) { lst.stream().forEach(el -> DiagramaDoSelecao(el, false, true)); PromoveToFirstSelect(lst.get(0)); } } return true; } return false; } public void repaint() { if (isCarregando) { return; } master.getBox().repaint(); } public void repaint(Rectangle r) { if (isCarregando) { return; } r = ZoomRectangle(r); master.getBox().repaint(r); } /** * Get the String residing on the clipboard. * * @return any text found on the Clipboard; if none found, return an empty String. Código copiado da internet. */ public static String getClipboardContents() { String result = ""; Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); //odd: the Object param of getContents is not currently used Transferable contents = clipboard.getContents(null); boolean hasTransferableText = (contents != null) && contents.isDataFlavorSupported(DataFlavor.stringFlavor); if (hasTransferableText) { try { result = (String) contents.getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException | IOException ex) { util.BrLogger.Logger("ERROR_DIAGRAMA_CLIPBOARD", ex.getMessage()); } } return result; } public static BufferedImage getClipboardContentsImage() { BufferedImage result = null; Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); //odd: the Object param of getContents is not currently used Transferable contents = clipboard.getContents(null); boolean hasTransferableImg = (contents != null) && contents.isDataFlavorSupported(DataFlavor.imageFlavor); if (hasTransferableImg) { try { result = (BufferedImage) contents.getTransferData(DataFlavor.imageFlavor); } catch (UnsupportedFlavorException | IOException ex) { util.BrLogger.Logger("ERROR_DIAGRAMA_CLIPBOARD", ex.getMessage()); } } return result; } @Override public String toString() { return super.toString() + "{" + Diagrama.SaveToXml(this, false) + "}"; } public static Diagrama Factory(TipoDeDiagrama otipo, Editor ed) { Diagrama res = null; switch (otipo) { case tpConceitual: res = new diagramas.conceitual.DiagramaConceitual(ed); break; case tpLogico: res = new diagramas.logico.DiagramaLogico(ed); break; case tpFluxo: res = new diagramas.fluxo.DiagramaFluxo(ed); break; case tpAtividade: res = new diagramas.atividade.DiagramaAtividade(ed); break; case tpEap: res = new diagramas.eap.DiagramaEap(ed); break; case tpLivre: res = new diagramas.livre.DiagramaLivre(ed); break; default: res = new Diagrama(ed); break; } ed.NomeieDiagrama(res); return res; } public class AcaoDiagrama extends Acao { public AcaoDiagrama(Editor editor, String texto, String ico, String descricao, String command) { super(editor, texto, ico, descricao, command); comm = command; } private Diagrama d = null; private String comm = ""; public AcaoDiagrama(Diagrama diag, String texto, String ico, String descricao, String command) { this(diag.getEditor(), texto, ico, descricao, command); d = diag; comm = command; } @Override public void actionPerformed(ActionEvent ev) { if (d != null) { d.rodaComando(comm); } } } public boolean EstaColandoNoMesmoDigDaOrigem() { return ((InfoDiagrama) infoDiagrama).IsTheShame(); } public int AlinhamentoH() { return ((InfoDiagrama) infoDiagrama).getAlinhamento_h(); } public int AlinhamentoV() { return ((InfoDiagrama) infoDiagrama).getAlinhamento_v(); } public void ExternalSuperAncorador() { superAncorador.Posicione(getSelecionado()); } //# Introduzino em 21/04/2017 public void InfoDiagrama_ToXmlValores(Document doc, Element me) { } //# Introduzino em 21/04/2017 public boolean InfoDiagrama_LoadFromXML(Element me, boolean colando) { return true; } /** * Mostra apenas os artefatos selecionados e os que estiverem ligados a eles. É setado para false no OnAfterLoad */ private boolean realce = false; public boolean isRealce() { return realce; } public void SetRealce(boolean realce) { this.realce = realce; } public void setRealce(boolean realce) { if (this.realce == realce) { return; } this.realce = realce; if (!realce) { getListaDeItens().stream().filter(fo -> fo instanceof FormaElementar).forEach(fo -> fo.setDisablePainted(false)); } else { final ArrayList<FormaElementar> res = new ArrayList<>(); getListaDeItens().stream().filter(f -> getItensSelecionados().indexOf(f) > -1).forEach(item -> { if (item instanceof Forma) { AdicionePrinFromRealce(res, item); //res.add(item); Forma f = (Forma) item; f.getListaDeFormasLigadas().forEach(lfl -> { AdicioneSubsFromRealce(res, lfl); }); f.getListaDeLigacoes().stream().filter(l -> l instanceof SuperLinha).forEach(lfl -> { AdicioneSubsFromRealce(res, lfl); }); } else if (item instanceof SuperLinha) { AdicionePrinFromRealce(res, item); SuperLinha sl = (SuperLinha) item; res.add(sl.getFormaPontaA()); res.add(sl.getFormaPontaB()); } }); getListaDeItens().stream().filter(f -> res.indexOf(f) == -1).forEach(fo -> fo.setDisablePainted(true)); } repaint(); } /** * Função acionada no momento de se coletar os artefatos que são parte de um artefato princiapal no momento de realçar o diagrama.<br> * É chamada pela função AdicionePrinFromRealce(...)<br> * * @param res: lista de eleentos coletado.<br> * @param item: item a ser analisado. */ protected void AdicioneSubsFromRealce(ArrayList<FormaElementar> res, FormaElementar item) { if (item instanceof Forma) { Forma f = (Forma) item; if (f.isParte()) { res.add((Forma) f.getPrincipal()); return; } } res.add(item); } /** * Função acionada no momento de se coletar os artefatos no momento de realçar o diagrama.<br> * <br> * * @param res: lista de eleentos coletado.<br> * @param item: item a ser analisado. */ protected void AdicionePrinFromRealce(ArrayList<FormaElementar> res, FormaElementar item) { AdicioneSubsFromRealce(res, item); } private final String v300 = "3.0.0"; private final String v310 = "3.1.0"; public boolean LoadVersao(String fromXml) { if (fromXml == null || fromXml.isEmpty()) { return false; } ArrayList<String> ver = new ArrayList<>(); ver.add(v300); ver.add(v310); ver.add(Diagrama.VERSAO_A + "." + Diagrama.VERSAO_B + "." + Diagrama.VERSAO_C); //Atual fromXml = fromXml.trim(); if (ver.indexOf(ver) == -1) { return false; } String[] v = fromXml.split("\\."); versaoA = v[0]; versaoB = v[1]; versaoC = v[2]; // String va = Diagrama.VERSAO_A; // String vb = Diagrama.VERSAO_B; // String vc = Diagrama.VERSAO_C; // try { // String[] v = fromXml.split("\\."); // if (v.length != 3) { // return false; // } // int a = Integer.valueOf(v[0]); // int b = Integer.valueOf(v[1]); // int c = Integer.valueOf(v[2]); // // int A = Integer.valueOf(va); // int B = Integer.valueOf(vb); // int C = Integer.valueOf(vc); // // if ((a > A) || (a == A && b > B) || (a == A && b == B && c > C)) { // return false; // } // // versaoA = v[0]; // versaoB = v[1]; // versaoC = v[2]; // // } catch (Exception ex) { // return false; // } return true; } }