Esempio n. 1
0
  public static boolean openFolderAvailable() {
    if (Base.isWindows() || Base.isMacOS()) return true;

    if (Base.isLinux()) {
      // Assume that this is set to something valid
      if (preferences.get("launcher.linux", null) != null) {
        return true;
      }

      // Attempt to use gnome-open
      try {
        Process p = Runtime.getRuntime().exec(new String[] {"gnome-open"});
        p.waitFor();
        // Not installed will throw an IOException (JDK 1.4.2, Ubuntu
        // 7.04)
        preferences.put("launcher.linux", "gnome-open");
        return true;
      } catch (Exception e) {
      }

      // Attempt with kde-open
      try {
        Process p = Runtime.getRuntime().exec(new String[] {"kde-open"});
        p.waitFor();
        preferences.put("launcher.linux", "kde-open");
        return true;
      } catch (Exception e) {
      }
    }
    return false;
  }
Esempio n. 2
0
  /**
   * Make sure the sketch hasn't been moved or deleted by some nefarious user. If they did, try to
   * re-create it and save. Only checks to see if the main folder is still around, but not its
   * contents.
   */
  protected void ensureExistence() {
    if (folder.exists()) return;

    Base.showWarning(
        "Sketch Disappeared",
        "The sketch folder has disappeared.\n "
            + "Will attempt to re-save in the same location,\n"
            + "but anything besides the code will be lost.",
        null);
    try {
      folder.mkdirs();
      modified = true;

      for (int i = 0; i < codeCount; i++) {
        code[i].save(); // this will force a save
      }
      for (int i = 0; i < hiddenCount; i++) {
        hidden[i].save(); // this will force a save
      }
      calcModified();

    } catch (Exception e) {
      Base.showWarning(
          "Could not re-save sketch",
          "Could not properly re-save the sketch. "
              + "You may be in trouble at this point,\n"
              + "and it might be time to copy and paste "
              + "your code to another text editor.",
          e);
    }
  }
Esempio n. 3
0
  /**
   * Implements the other cross-platform headache of opening a folder in the machine's native file
   * browser.
   */
  public static void openFolder(File file) {
    try {
      String folder = file.getAbsolutePath();

      if (Base.isWindows()) {
        // doesn't work
        // Runtime.getRuntime().exec("cmd /c \"" + folder + "\"");

        // works fine on winxp, prolly win2k as well
        Runtime.getRuntime().exec("explorer \"" + folder + "\"");

        // not tested
        // Runtime.getRuntime().exec("start explorer \"" + folder +
        // "\"");

      } else if (Base.isMacOS()) {
        openURL(folder); // handles char replacement, etc

      } else if (Base.isLinux()) {
        String launcher = preferences.get("launcher.linux", null);
        if (launcher != null) {
          Runtime.getRuntime().exec(new String[] {launcher, folder});
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  protected JComponent createBeepPanel() {
    JPanel beepPanel = new JPanel();

    final JFormattedTextField beepFreq = new JFormattedTextField(Base.getLocalFormat());
    final JFormattedTextField beepDur = new JFormattedTextField(Base.getLocalFormat());
    final JButton beepButton = new JButton("Beep Beep!");

    beepFreq.setColumns(5);
    beepDur.setColumns(5);

    final int EFFECT_DO_IMMEDATELY = 0; // /
    beepButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent arg0) {
            Base.logger.severe("running sendBeep");
            machine.runCommand(
                new SendBeep(
                    ((Number) beepFreq.getValue()).intValue(),
                    ((Number) beepDur.getValue()).intValue(),
                    EFFECT_DO_IMMEDATELY));
          }
        });

    beepPanel.add(new JLabel("Frequency"), "split");
    beepPanel.add(beepFreq, "growy");
    beepPanel.add(new JLabel("Duration"), "gap unrel");
    beepPanel.add(beepDur, "growx");
    beepPanel.add(beepButton, "gap unrel");
    return beepPanel;
  }
Esempio n. 5
0
  public String getMachineInfo() {
    Driver driver = Base.getMachineLoader().getDriver();

    String info = new String();

    info += "System Information" + "\n";
    info += " ReplicatorG version: " + Base.VERSION_NAME + "\n";
    info += " Java version: " + System.getProperty("java.version") + "\n";

    info += "\n";
    info += "Machine" + "\n";
    info += " Profile Name: " + Base.preferences.get("machine.name", "") + "\n";
    info += " Driver Type: " + Base.getMachineLoader().getDriver().getDriverName() + "\n";
    info += " Name: " + Base.getMachineLoader().getMachine().getMachineName() + "\n";

    // TODO: Only if a printer is connected?
    info += " Motherboard firmware version: " + driver.getFirmwareInfo() + "\n";
    // Status dump

    // Communication Statistics
    if (driver instanceof OnboardParameters) {
      CommunicationStatistics stats = ((OnboardParameters) driver).getCommunicationStatistics();
      info += " Motherboard communication statistics" + "\n";
      info += "  Number of packets received from the USB interface:" + stats.packetCount + "\n";
      info += "  Number of packets sent over the RS485 interface:" + stats.sentPacketCount + "\n";
      info +=
          "  Number of packets sent over the RS485 interface that were not responded to:"
              + stats.packetFailureCount
              + "\n";
      info += "  Number of packet retries attempted:" + stats.packetRetryCount + "\n";
      info +=
          "  Number of bytes received over the RS485 interface that were discarded as noise:"
              + stats.noiseByteCount
              + "\n";
    }
    // EEPROM dump

    // Toolhead info (per toolhead)

    // Default skeinforge version/profile info?

    // Machine Driver XML dump
    info += "\n";
    info += "Machine Driver XML:" + "\n";
    Node machineNode = MachineFactory.getMachineNode(Base.preferences.get("machine.name", ""));
    if (machineNode != null) {
      info += convertNodeToHtml(machineNode) + "\n";
    }

    // Test communication

    return info;
  }
Esempio n. 6
0
  /**
   * Add a file to the sketch.
   *
   * <p>.gcode files will be added to the sketch folder. <br>
   * All other files will be added to the "data" folder.
   *
   * <p>If they don't exist already, the "code" or "data" folder will be created.
   *
   * <p>
   *
   * @return true if successful.
   */
  public boolean addFile(File sourceFile) {
    String filename = sourceFile.getName();
    File destFile = null;
    boolean addingCode = false;

    destFile = new File(this.folder, filename);
    addingCode = true;

    // make sure they aren't the same file
    if (!addingCode && sourceFile.equals(destFile)) {
      Base.showWarning(
          "You can't fool me",
          "This file has already been copied to the\n"
              + "location where you're trying to add it.\n"
              + "I ain't not doin nuthin'.",
          null);
      return false;
    }

    // in case the user is "adding" the code in an attempt
    // to update the sketch's tabs
    if (!sourceFile.equals(destFile)) {
      try {
        Base.copyFile(sourceFile, destFile);

      } catch (IOException e) {
        Base.showWarning("Error adding file", "Could not add '" + filename + "' to the sketch.", e);
        return false;
      }
    }

    // make the tabs update after this guy is added
    if (addingCode) {
      String newName = destFile.getName();
      int newFlavor = -1;
      if (newName.toLowerCase().endsWith(".gcode")) {
        newName = newName.substring(0, newName.length() - 6);
        newFlavor = GCODE;
      }

      // see also "nameCode" for identical situation
      SketchCode newCode = new SketchCode(newName, destFile, newFlavor);
      insertCode(newCode);
      sortCode();
      setCurrent(newName);
      editor.header.repaint();
    }
    return true;
  }
Esempio n. 7
0
  public RealtimePanel(MachineInterface machine2) {
    super("Real time control and tuning");
    Image icon = Base.getImage("images/icon.gif", this);
    setIconImage(icon);

    machine = machine2;
    driver = machine.getDriver();

    ((RealtimeControl) driver).enableRealtimeControl(true);

    // create all our GUI interfaces
    JPanel speedPanel = new JPanel();
    JPanel extrusionPanel = new JPanel();
    add(new JLabel("Build speed (during extrusion)"));

    // Speed
    feedrateControl = new ControlSlider("Feedrate", "%", 5, 800, 100, speedPanel);
    // feedrateControl.getSlider().setMajorTickSpacing(10);
    Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>();
    labelTable.put(new Integer(10), new JLabel("Slow"));
    labelTable.put(new Integer(100), new JLabel(""));
    labelTable.put(new Integer(300), new JLabel("Fast"));
    labelTable.put(new Integer(500), new JLabel("Insane!"));
    feedrateControl.slider.setLabelTable(labelTable);

    //		add(new JLabel("Travel feedrate (no extrusion"),"growx,wrap");
    travelFeedrateControl = new ControlSlider("Travel feedrate", "%", 5, 800, 100, speedPanel);
    travelFeedrateControl.slider.setLabelTable(labelTable);

    // Extrusion
    extrusionPanel.add(new JLabel("Extrusion"), "growx,wrap");
    extrusionControl = new ControlSlider("Material muliplier", "%", 5, 500, 100, extrusionPanel);
    // TODO: extrusion scaling is not implemented in the driver yet.
    extrusionControl.slider.setEnabled(false);
    extrusionControl.field.setEnabled(false);

    mainPanel = new JPanel();
    mainPanel.setLayout(new MigLayout());
    mainPanel.add(speedPanel, "flowy,wrap");
    mainPanel.add(extrusionPanel, "flowy,wrap");

    new SpeedLimit(mainPanel);

    // Show comms debug checkbox
    JCheckBox showCommsDebug = new JCheckBox("Show communications");
    if (((RealtimeControl) driver).getDebugLevel() >= 2) showCommsDebug.setSelected(true);

    showCommsDebug.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            if (((JCheckBox) e.getSource()).isSelected()) {
              ((RealtimeControl) driver).setDebugLevel(2);
            } else {
              ((RealtimeControl) driver).setDebugLevel(1);
            }
          }
        });
    mainPanel.add(showCommsDebug, "flowy,wrap");
    add(mainPanel);
  }
Esempio n. 8
0
 public void mouseDragged(MouseEvent e) {
   if (startPoint == null) return;
   Point p = e.getPoint();
   DragMode mode = DragMode.NONE;
   if (Base.isMacOS()) {
     if (button == MouseEvent.BUTTON1 && !e.isShiftDown()) {
       mode = DragMode.TRANSLATE_OBJECT;
     }
   } else {
     if (button == MouseEvent.BUTTON1) {
       mode = DragMode.TRANSLATE_OBJECT;
     }
   }
   double xd = (double) (p.x - startPoint.x);
   double yd = -(double) (p.y - startPoint.y);
   switch (mode) {
     case NONE:
       super.mouseDragged(e);
       break;
     case TRANSLATE_OBJECT:
       doTranslate(xd, yd);
       break;
   }
   startPoint = p;
 }
Esempio n. 9
0
  /**
   * path is location of the main .gcode file, because this is also simplest to use when opening the
   * file from the finder/explorer.
   */
  public Sketch(MainWindow editor, String path) throws IOException {
    this.editor = editor;

    File mainFile = new File(path);
    // System.out.println("main file is " + mainFile);

    mainFilename = mainFile.getName();
    // System.out.println("main file is " + mainFilename);

    // get the name of the sketch by chopping .gcode
    // off of the main file name
    if (mainFilename.endsWith(".gcode")) {
      name = mainFilename.substring(0, mainFilename.length() - 6);
    } else {
      name = mainFilename;
      mainFilename = mainFilename + ".gcode";
    }

    tempBuildFolder = Base.getBuildFolder();
    // Base.addBuildFolderToClassPath();

    String parentPath = new File(path).getParent();
    if (parentPath == null) {
      parentPath = ".";
    }
    folder = new File(parentPath);
    // System.out.println("sketch dir is " + folder);

    load();
  }
Esempio n. 10
0
  /** Save all code in the current sketch. */
  public boolean save() throws IOException {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // first get the contents of the editor text area
    if (current.modified) {
      current.program = editor.getText();
    }

    // don't do anything if not actually modified
    // if (!modified) return false;

    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "Sketch is read-only",
          "Some files are marked \"read-only\", so you'll\n"
              + "need to re-save this sketch to another location.");
      // if the user cancels, give up on the save()
      if (!saveAs()) return false;
    }

    for (int i = 0; i < codeCount; i++) {
      if (code[i].modified) code[i].save();
    }
    calcModified();
    return true;
  }
Esempio n. 11
0
  /** Save all code in the current sketch. */
  public boolean save() throws IOException {
    if (mainFilename == null) {
      return saveAs();
    }

    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "File is read-only",
          "This file is marked \"read-only\", so you'll\n"
              + "need to re-save this file to another location.");
      // if the user cancels, give up on the save()
      if (!saveAs()) return false;
      return true;
    }

    BuildCode code = getCode();
    if (code != null) {
      if (hasMainWindow) {
        if (code.isModified()) {
          code.program = editor.getText();
          code.save();
        }
      }
    }
    BuildModel model = getModel();
    if (model != null) {
      if (model.isModified()) {
        model.save();
      }
    }
    return true;
  }
Esempio n. 12
0
  /**
   * Change internal settings based on what was chosen in the prefs, then send a message to the
   * editor saying that it's time to do the same.
   */
  public void applyFrame() {
    // put each of the settings into the table
    String newSizeText = fontSizeField.getText();
    try {
      int newSize = Integer.parseInt(newSizeText.trim());
      String fontName = Base.preferences.get("editor.font", "Monospaced,plain,12");
      if (fontName != null) {
        String pieces[] = fontName.split(",");
        pieces[2] = String.valueOf(newSize);
        StringBuffer buf = new StringBuffer();
        for (String piece : pieces) {
          if (buf.length() > 0) buf.append(",");
          buf.append(piece);
        }
        Base.preferences.put("editor.font", buf.toString());
      }

    } catch (Exception e) {
      Base.logger.warning("ignoring invalid font size " + newSizeText);
    }
    String origUpdateUrl = Base.preferences.get("replicatorg.updates.url", "");
    if (!origUpdateUrl.equals(firmwareUpdateUrlField.getText())) {
      FirmwareUploader.invalidateFirmware();
      Base.preferences.put("replicatorg.updates.url", firmwareUpdateUrlField.getText());
      FirmwareUploader.checkFirmware(); // Initiate a new firmware check
    }

    String logPath = logPathField.getText();
    Base.preferences.put("replicatorg.logpath", logPath);
    Base.setLogFile(logPath);

    editor.applyPreferences();
  }
Esempio n. 13
0
 /**
  * @param path The relative path to the file in the .replicatorG directory
  * @param autoCopy If true, copy over the file of the same name in the application directory if
  *     none is found in the prefs directory.
  * @return
  */
 public static File getUserFile(String path, boolean autoCopy) {
   if (path.contains("..")) {
     Base.logger.info("Attempted to access parent directory in " + path + ", skipping");
     return null;
   }
   // First look in the user's local .replicatorG directory for the path.
   File f = new File(getUserDirectory(), path);
   // Make the parent file if not already there
   File dir = f.getParentFile();
   if (!dir.exists()) {
     dir.mkdirs();
   }
   if (autoCopy && !f.exists()) {
     // Check if there's an application-level version
     File original = getApplicationFile(path);
     // If so, copy it over
     if (original.exists()) {
       try {
         Base.copyFile(original, f);
       } catch (IOException ioe) {
         Base.logger.log(
             Level.SEVERE, "Couldn't copy " + path + " to your local .replicatorG directory", f);
       }
     }
   }
   return f;
 }
Esempio n. 14
0
  public void hideCode() {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // if read-only, give an error
    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "Sketch is Read-Only",
          "Some files are marked \"read-only\", so you'll\n"
              + "need to re-save the sketch in another location,\n"
              + "and try again.");
      return;
    }

    // don't allow hide of the main code
    // TODO maybe gray out the menu on setCurrent(0)
    if (currentIndex == 0) {
      Base.showMessage(
          "Can't do that", "You cannot hide the main " + ".gcode file from a sketch\n");
      return;
    }

    // rename the file
    File newFile = new File(current.file.getAbsolutePath() + ".x");
    if (!current.file.renameTo(newFile)) {
      Base.showWarning("Error", "Could not hide " + "\"" + current.file.getName() + "\".", null);
      return;
    }
    current.file = newFile;

    // move it to the hidden list
    if (hiddenCount == hidden.length) {
      SketchCode temp[] = new SketchCode[hiddenCount + 1];
      System.arraycopy(hidden, 0, temp, 0, hiddenCount);
      hidden = temp;
    }
    hidden[hiddenCount++] = current;

    // remove it from the main list
    removeCode(current);

    // update the tabs
    setCurrent(0);
    editor.header.repaint();
  }
Esempio n. 15
0
 private void showCurrentSettings() {
   Font editorFont = Base.getFontPref("editor.font", "Monospaced,plain,12");
   fontSizeField.setText(String.valueOf(editorFont.getSize()));
   String firmwareUrl =
       Base.preferences.get("replicatorg.updates.url", FirmwareUploader.DEFAULT_UPDATES_URL);
   firmwareUpdateUrlField.setText(firmwareUrl);
   String logPath = Base.preferences.get("replicatorg.logpath", "");
   logPathField.setText(logPath);
 }
Esempio n. 16
0
 /**
  * Generic Constructor. Creates an output file and registers as a machineListener
  *
  * @filename : desired output file
  */
 public DataCapture(String filename) {
   try {
     outFile = new FileWriter(filename);
   } catch (IOException e) {
     Base.logger.severe("Couldn't open data capture file for writing:" + e.getMessage());
   }
   // Listen to the machine, do you hear what it is telling you?
   Base.getMachineLoader().addMachineListener(this);
 }
 /**
  * This gets the first feedrate used in a layer
  *
  * @param l
  * @return
  */
 private String getFirstFeedrate(final Layer l) {
   final List<String> search = l.getCommands();
   GCodeCommand gcode;
   for (int i = 0; i < search.size(); i++) {
     gcode = new GCodeCommand(search.get(i));
     if (gcode.getCodeValue('F') != -1)
       return "F" + Base.getGcodeFormat().format(gcode.getCodeValue('F'));
   }
   return "";
 }
Esempio n. 18
0
  public void unhideCode(String what) {
    SketchCode unhideCode = null;
    String name = what.substring(0, (what.indexOf(".") == -1 ? what.length() : what.indexOf(".")));
    String extension = what.indexOf(".") == -1 ? "" : what.substring(what.indexOf("."));

    for (int i = 0; i < hiddenCount; i++) {
      if (hidden[i].name.equals(name)
          && Sketch.flavorExtensionsShown[hidden[i].flavor].equals(extension)) {
        // unhideIndex = i;
        unhideCode = hidden[i];

        // remove from the 'hidden' list
        for (int j = i; j < hiddenCount - 1; j++) {
          hidden[j] = hidden[j + 1];
        }
        hiddenCount--;
        break;
      }
    }
    // if (unhideIndex == -1) {
    if (unhideCode == null) {
      System.err.println("internal error: could find " + what + " to unhide.");
      return;
    }
    if (!unhideCode.file.exists()) {
      Base.showMessage("Can't unhide", "The file \"" + what + "\" no longer exists.");
      // System.out.println(unhideCode.file);
      return;
    }
    String unhidePath = unhideCode.file.getAbsolutePath();
    File unhideFile = new File(unhidePath.substring(0, unhidePath.length() - 2));

    if (!unhideCode.file.renameTo(unhideFile)) {
      Base.showMessage(
          "Can't unhide", "The file \"" + what + "\" could not be" + "renamed and unhidden.");
      return;
    }
    unhideCode.file = unhideFile;
    insertCode(unhideCode);
    sortCode();
    setCurrent(unhideCode.name);
    editor.header.repaint();
  }
Esempio n. 19
0
  /** Cleanup temporary files used during a build/run. */
  public void cleanup() {
    // if the java runtime is holding onto any files in the build dir, we
    // won't be able to delete them, so we need to force a gc here
    System.gc();

    // note that we can't remove the builddir itself, otherwise
    // the next time we start up, internal runs using Runner won't
    // work because the build dir won't exist at startup, so the classloader
    // will ignore the fact that that dir is in the CLASSPATH in run.sh
    Base.removeDescendants(tempBuildFolder);
  }
  public DualStrusionConstruction(
      File leftFile,
      File rightFile,
      MutableGCodeSource startSource,
      MutableGCodeSource endSource,
      MachineType type,
      boolean useWipes) {
    this.leftFile = leftFile;
    this.rightFile = rightFile;
    this.useWipes = useWipes;
    this.machineType = type;
    startGCode = startSource.copy();
    endGCode = endSource.copy();
    if (useWipes) {
      leftWipe =
          Base.getMachineLoader().getMachineInterface().getModel().getWipeFor(ToolheadAlias.LEFT);
      rightWipe =
          Base.getMachineLoader().getMachineInterface().getModel().getWipeFor(ToolheadAlias.RIGHT);

      if (leftWipe == null || rightWipe == null) {
        String error =
            "Could not find wipes for the current machine: "
                + Base.getMachineLoader().getMachineInterface().getModel().toString()
                + ". Continuing without wipes.";
        JOptionPane.showConfirmDialog(
            null,
            error,
            "Could not find wipes!",
            JOptionPane.DEFAULT_OPTION,
            JOptionPane.ERROR_MESSAGE);

        useWipes = false;
      }
    } else {
      leftWipe = null;
      rightWipe = null;
    }
  }
Esempio n. 21
0
  public void newCode() {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // if read-only, give an error
    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "Sketch is Read-Only",
          "Some files are marked \"read-only\", so you'll\n"
              + "need to re-save the sketch in another location,\n"
              + "and try again.");
      return;
    }

    renamingCode = false;
    // editor.status.edit("Name for new file:", "");
  }
Esempio n. 22
0
  public void renameCode() {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // if read-only, give an error
    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "Sketch is Read-Only",
          "Some files are marked \"read-only\", so you'll\n"
              + "need to re-save the sketch in another location,\n"
              + "and try again.");
      return;
    }

    // ask for new name of file (internal to window)
    // TODO maybe just popup a text area?
    renamingCode = true;
    // editor.status.edit(prompt, oldName);
  }
  private ControlPanelWindow(MachineInterface newMachine) {
    super("Control Panel");

    Image icon = Base.getImage("images/icon.gif", this);
    setIconImage(icon);

    // save our machine!
    machine = newMachine;

    machine.runCommand(new InvalidatePosition());

    // Listen to it-- stop and close if we're in build mode.
    Base.getMachineLoader().addMachineListener(this);

    // default behavior
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    // no menu bar.
    setJMenuBar(createMenuBar());

    chooser = new JColorChooser(Color.BLACK);

    ActionListener okListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Color ledColor = chooser.getColor();
            Base.logger.severe("running setLedStrip");
            try {
              machine.getDriver().setLedStrip(ledColor, 0);
            } catch (replicatorg.drivers.RetryException f) {
              Base.logger.severe("foo" + f.toString());
            }
            // machine.runCommand(new SetLedStrip(ledColor, 0));
            ledStripButton.setText(ShowColorChooserAction.buttonStringFromColor(ledColor));
          }
        };

    ledStripButton =
        new JButton(new ShowColorChooserAction(this, chooser, okListener, null, Color.BLACK));

    // create all our GUI interfaces
    mainPanel = new JPanel();
    mainPanel.setLayout(new MigLayout("gap 5, ins 5, flowy"));

    jogPanel = new JogPanel(machine);
    mainPanel.add(jogPanel, "split 4, growx, growy");
    mainPanel.add(createActivationPanel(), "split, growx");
    if (newMachine.getMachineType() == MachineType.THE_REPLICATOR) {
      mainPanel.add(ledStripButton, "growx");
      //			mainPanel.add(createBeepPanel(), "growx");
    }
    mainPanel.add(alternateToolsPanel(), "newline, growy");

    this.setResizable(false);
    add(mainPanel);

    // add our listener hooks.
    addWindowListener(this);
    // addWindowFocusListener(this);
    // addWindowStateListener(this);

    // start our various threads.
    updateThread = new UpdateThread(this);
    updateThread.start();
    pollThread = new PollThread(machine);
    pollThread.start();
  }
public class ExtruderOnboardParameters extends JPanel {
  private static final long serialVersionUID = 6353987389397209816L;
  private OnboardParameters target;

  // Float gui objects show at least 2 places, max 8 places for clarity it's a float
  private static final NumberFormat floatFormat = (NumberFormat) Base.getLocalFormat().clone();

  {
    floatFormat.setMaximumFractionDigits(8);
    floatFormat.setMinimumFractionDigits(2);
  }

  private static final NumberFormat mmNumberFormat = (NumberFormat) Base.getLocalFormat().clone();

  {
    floatFormat.setMaximumFractionDigits(0);
    floatFormat.setMinimumFractionDigits(0);
  }

  interface Commitable {
    public void commit();
    // In a sane universe, this would be called "validate".  In a sane universe
    // where Java actually implemented inheritance in a sane and happy manner.
    public boolean isCommitable();
  }

  final int FIELD_WIDTH = 10;

  class ThermistorTablePanel extends JPanel implements Commitable {
    private static final long serialVersionUID = 7765098486598830410L;

    private JFormattedTextField betaField = new JFormattedTextField(floatFormat);
    private JFormattedTextField r0Field = new JFormattedTextField(floatFormat);
    private JFormattedTextField t0Field = new JFormattedTextField(floatFormat);
    // Toolhead or Heated Platform?
    private final int which;

    //		private final ToolModel tool;
    private final int toolIndex;

    ThermistorTablePanel(int which, String titleText, int toolIndex /*ToolModel tool*/) {
      super(new MigLayout());
      this.which = which;
      // this.tool = tool;
      this.toolIndex = toolIndex;
      setBorder(BorderFactory.createTitledBorder(titleText));
      betaField.setColumns(FIELD_WIDTH);
      r0Field.setColumns(FIELD_WIDTH);
      t0Field.setColumns(FIELD_WIDTH);

      double beta = target.getBeta(which, toolIndex);
      if (beta == -1) beta = 4066;

      betaField.setValue((int) beta);
      add(new JLabel("Beta"));
      add(betaField, "wrap");

      double r0 = target.getR0(which, toolIndex);
      if (r0 == -1) r0 = 100000;

      r0Field.setValue((int) r0);
      add(new JLabel("Thermistor Resistance"));
      add(r0Field, "wrap");

      double t0 = target.getT0(which, toolIndex);
      if (t0 == -1) t0 = 25;

      t0Field.setValue((int) t0);
      add(new JLabel("Base Temperature"));
      add(t0Field, "wrap");
    }

    public void commit() {
      int beta = ((Number) betaField.getValue()).intValue();
      int r0 = ((Number) r0Field.getValue()).intValue();
      int t0 = ((Number) t0Field.getValue()).intValue();
      target.createThermistorTable(which, r0, t0, beta, this.toolIndex);
    }

    public boolean isCommitable() {
      return true;
    }
  }

  Vector<Commitable> commitList = new Vector<Commitable>();

  private boolean commit() {
    for (Commitable c : commitList) {
      if (!c.isCommitable()) {
        return false;
      }
    }

    for (Commitable c : commitList) {
      c.commit();
    }
    JOptionPane.showMessageDialog(
        this,
        "Changes will not take effect until the extruder board is reset.  You can \n"
            + "do this by turning your machine off and then on, or by disconnecting and \n"
            + "reconnecting the extruder cable.  Make sure you don't still have a USB2TTL \n"
            + "cable attached to the extruder controller, as the cable will keep the board \n"
            + "from resetting.",
        "Extruder controller reminder",
        JOptionPane.INFORMATION_MESSAGE);
    return true;
  }

  private class BackoffPanel extends JPanel implements Commitable {
    private static final long serialVersionUID = 6593800743174557032L;

    private JFormattedTextField stopMsField = new JFormattedTextField(mmNumberFormat);
    private JFormattedTextField reverseMsField = new JFormattedTextField(mmNumberFormat);
    private JFormattedTextField forwardMsField = new JFormattedTextField(mmNumberFormat);
    private JFormattedTextField triggerMsField = new JFormattedTextField(mmNumberFormat);
    // private final ToolModel tool;
    private int toolIndex;

    BackoffPanel(int toolIndex /*ToolModel tool*/) {
      this.toolIndex = toolIndex;

      setLayout(new MigLayout());
      setBorder(BorderFactory.createTitledBorder("Reversal parameters"));
      stopMsField.setColumns(FIELD_WIDTH);
      reverseMsField.setColumns(FIELD_WIDTH);
      forwardMsField.setColumns(FIELD_WIDTH);
      triggerMsField.setColumns(FIELD_WIDTH);

      add(new JLabel("Time to pause (ms)"));
      add(stopMsField, "wrap");
      add(new JLabel("Time to reverse (ms)"));
      add(reverseMsField, "wrap");
      add(new JLabel("Time to advance (ms)"));
      add(forwardMsField, "wrap");
      add(new JLabel("Min. extrusion time before reversal (ms)"));
      add(triggerMsField, "wrap");
      OnboardParameters.BackoffParameters bp = target.getBackoffParameters(toolIndex);
      stopMsField.setValue(bp.stopMs);
      reverseMsField.setValue(bp.reverseMs);
      forwardMsField.setValue(bp.forwardMs);
      triggerMsField.setValue(bp.triggerMs);
    }

    public void commit() {
      OnboardParameters.BackoffParameters bp = new OnboardParameters.BackoffParameters();
      bp.forwardMs = ((Number) forwardMsField.getValue()).intValue();
      bp.reverseMs = ((Number) reverseMsField.getValue()).intValue();
      bp.stopMs = ((Number) stopMsField.getValue()).intValue();
      bp.triggerMs = ((Number) triggerMsField.getValue()).intValue();
      target.setBackoffParameters(bp, toolIndex);
    }

    public boolean isCommitable() {
      return true;
    }
  }

  private class ExtraFeaturesPanel extends JPanel implements Commitable {
    private JCheckBox swapMotors;
    private JComboBox extCh, hbpCh, abpCh;
    private OnboardParameters.ExtraFeatures ef;

    // private final ToolModel tool;
    private int toolIndex;

    ExtraFeaturesPanel(int toolIndex /*ToolModel tool*/) {
      // this.tool = tool;
      this.toolIndex = toolIndex;
      setLayout(new MigLayout());
      ef = target.getExtraFeatures(toolIndex);
      swapMotors =
          new JCheckBox("Use 2A/2B to drive DC motor instead of 1A/1B", ef.swapMotorController);
      add(swapMotors, "span 3,growx,wrap");
      Vector<String> choices = new Vector<String>();
      choices.add("Channel A");
      choices.add("Channel B");
      choices.add("Channel C");
      extCh = new JComboBox(choices);
      extCh.setSelectedIndex(ef.heaterChannel);
      add(new JLabel("Extruder heater uses:"));
      add(extCh);
      add(new JLabel("(default ch. B)"), "wrap");
      hbpCh = new JComboBox(choices);
      hbpCh.setSelectedIndex(ef.hbpChannel);
      add(new JLabel("Platform heater uses:"));
      add(hbpCh);
      add(new JLabel("(default ch. A)"), "wrap");
      abpCh = new JComboBox(choices);
      abpCh.setSelectedIndex(ef.abpChannel);
      add(new JLabel("ABP motor uses:"));
      add(abpCh);
      add(new JLabel("(default ch. C)"), "wrap");
    }

    public void commit() {
      ef.swapMotorController = swapMotors.isSelected();
      ef.heaterChannel = extCh.getSelectedIndex();
      ef.hbpChannel = hbpCh.getSelectedIndex();
      ef.abpChannel = abpCh.getSelectedIndex();
      target.setExtraFeatures(ef, toolIndex);
    }

    public boolean isCommitable() {
      int a = extCh.getSelectedIndex();
      int b = hbpCh.getSelectedIndex();
      int c = abpCh.getSelectedIndex();
      if (a == b || b == c || a == c) {
        JOptionPane.showMessageDialog(
            this,
            "Two or more features are using the same mosfet channel!",
            "Channel conflict",
            JOptionPane.ERROR_MESSAGE);
        return false;
      }
      return true;
    }
  }

  private class PIDPanel extends JPanel implements Commitable {
    private NumberFormat eightPlaces = (NumberFormat) floatFormat.clone();

    {
      eightPlaces.setMaximumFractionDigits(8);
    }

    private JFormattedTextField pField = new JFormattedTextField(floatFormat);
    private JFormattedTextField iField = new JFormattedTextField(eightPlaces);
    private JFormattedTextField dField = new JFormattedTextField(floatFormat);
    private final int which;
    // private final ToolModel tool;
    private int toolIndex;

    PIDPanel(int which, String name, int toolIndex) {
      this.which = which;
      this.toolIndex = toolIndex;
      setLayout(new MigLayout());
      setBorder(BorderFactory.createTitledBorder(name));
      pField.setColumns(FIELD_WIDTH);
      iField.setColumns(FIELD_WIDTH);
      dField.setColumns(FIELD_WIDTH);

      add(new JLabel("P parameter"));
      add(pField, "wrap");
      add(new JLabel("I parameter"));
      add(iField, "wrap");
      add(new JLabel("D parameter"));
      add(dField, "wrap");
      OnboardParameters.PIDParameters pp = target.getPIDParameters(which, toolIndex);
      pField.setValue(pp.p);
      iField.setValue(pp.i);
      dField.setValue(pp.d);
    }

    public void commit() {
      OnboardParameters.PIDParameters pp = new OnboardParameters.PIDParameters();
      pp.p = ((Number) pField.getValue()).floatValue();
      pp.i = ((Number) iField.getValue()).floatValue();
      pp.d = ((Number) dField.getValue()).floatValue();
      target.setPIDParameters(which, pp, toolIndex);
    }

    public boolean isCommitable() {
      return true;
    }
  }

  class RegulatedCoolingFan extends JPanel implements Commitable {
    private static final long serialVersionUID = 7765098486598830410L;
    private JCheckBox coolingFanEnabled;

    private JFormattedTextField coolingFanSetpoint = new JFormattedTextField(floatFormat);

    // private final ToolModel tool;
    private final int toolIndex;

    RegulatedCoolingFan(/*ToolModel tool*/ int toolIndex) {
      super(new MigLayout());

      // this.tool = tool;
      this.toolIndex = toolIndex;
      coolingFanEnabled =
          new JCheckBox(
              "Enable regulated cooling fan (stepper extruders only)",
              target.getCoolingFanEnabled(toolIndex));
      add(coolingFanEnabled, "growx,wrap");

      coolingFanSetpoint.setColumns(FIELD_WIDTH);

      coolingFanSetpoint.setValue((int) target.getCoolingFanSetpoint(toolIndex));
      add(new JLabel("Setpoint (C)"));
      add(coolingFanSetpoint, "wrap");
    }

    public void commit() {
      boolean enabled = coolingFanEnabled.isSelected();
      int setpoint = ((Number) coolingFanSetpoint.getValue()).intValue();
      target.setCoolingFanParameters(enabled, setpoint, toolIndex);
    }

    public boolean isCommitable() {
      return true;
    }
  }

  public ExtruderOnboardParameters(OnboardParameters target, ToolModel tool, JFrame parent) {
    this.target = target;
    int toolIndex = tool.getIndex();

    Version v = new Version(0, 0);
    if (target instanceof Sanguino3GDriver) {
      v = ((Sanguino3GDriver) target).getToolVersion();
    }

    setLayout(new MigLayout());

    ThermistorTablePanel ttp;

    if (tool.hasExtruderThermistor()) {
      ttp = new ThermistorTablePanel(OnboardParameters.EXTRUDER, "Extruder thermistor", toolIndex);
      this.add(ttp);
      commitList.add(ttp);
    }

    if (tool.hasAutomatedPlatform()) {
      ttp =
          new ThermistorTablePanel(
              OnboardParameters.BUILD_PLATFORM, "Heated build platform thermistor", toolIndex);
      this.add(ttp, "wrap");
      commitList.add(ttp);
    }

    if (tool.hasExtruderThermocouple()) {
      PIDPanel pidPanel =
          new PIDPanel(OnboardParameters.EXTRUDER, "Extruder PID parameters", toolIndex);
      this.add(pidPanel, "growx");
      commitList.add(pidPanel);
    }

    if (v.atLeast(new Version(2, 4))) {
      PIDPanel pp =
          new PIDPanel(OnboardParameters.BUILD_PLATFORM, "Heated build platform", toolIndex);
      this.add(pp, "growx,wrap");
      commitList.add(pp);
    }

    if (v.atLeast(new Version(2, 9))) {
      RegulatedCoolingFan rcf = new RegulatedCoolingFan(toolIndex);
      this.add(rcf, "span 2,growx,wrap");
      commitList.add(rcf);
    }

    String machineType = target.getMachineType();
    if (!(machineType.equals("MightyBoard")
        || machineType.equals("The Replicator")
        || machineType.equals("MightyBoard(unverified)"))) {
      JButton commitButton = new JButton("Commit Changes");
      commitButton.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
              if (ExtruderOnboardParameters.this.commit()) {}
            }
          });
      add(commitButton, "newline, span 2");
    }
  }
}
Esempio n. 25
0
  /**
   * Implements the cross-platform headache of opening URLs TODO This code should be replaced by
   * PApplet.link(), however that's not a static method (because it requires an AppletContext when
   * used as an applet), so it's mildly trickier than just removing this method.
   */
  public static void openURL(String url) {
    // System.out.println("opening url " + url);
    try {
      if (Base.isWindows()) {
        // this is not guaranteed to work, because who knows if the
        // path will always be c:\progra~1 et al. also if the user has
        // a different browser set as their default (which would
        // include me) it'd be annoying to be dropped into ie.
        // Runtime.getRuntime().exec("c:\\progra~1\\intern~1\\iexplore "
        // + currentDir

        // the following uses a shell execute to launch the .html file
        // note that under cygwin, the .html files have to be chmodded
        // +x
        // after they're unpacked from the zip file. i don't know why,
        // and don't understand what this does in terms of windows
        // permissions. without the chmod, the command prompt says
        // "Access is denied" in both cygwin and the "dos" prompt.
        // Runtime.getRuntime().exec("cmd /c " + currentDir +
        // "\\reference\\" +
        // referenceFile + ".html");
        if (url.startsWith("http://")) {
          // open dos prompt, give it 'start' command, which will
          // open the url properly. start by itself won't work since
          // it appears to need cmd
          Runtime.getRuntime().exec("cmd /c start " + url);
        } else {
          // just launching the .html file via the shell works
          // but make sure to chmod +x the .html files first
          // also place quotes around it in case there's a space
          // in the user.dir part of the url
          Runtime.getRuntime().exec("cmd /c \"" + url + "\"");
        }

      } else if (Base.isMacOS()) {
        // com.apple.eio.FileManager.openURL(url);

        if (!url.startsWith("http://")) {
          // prepend file:// on this guy since it's a file
          url = "file://" + url;

          // replace spaces with %20 for the file url
          // otherwise the mac doesn't like to open it
          // can't just use URLEncoder, since that makes slashes into
          // %2F characters, which is no good. some might say
          // "useless"
          if (url.indexOf(' ') != -1) {
            StringBuffer sb = new StringBuffer();
            char c[] = url.toCharArray();
            for (int i = 0; i < c.length; i++) {
              if (c[i] == ' ') {
                sb.append("%20");
              } else {
                sb.append(c[i]);
              }
            }
            url = sb.toString();
          }
        }
        com.apple.mrj.MRJFileUtils.openURL(url);

      } else if (Base.isLinux()) {
        String launcher = preferences.get("launcher.linux", "gnome-open");
        if (launcher != null) {
          Runtime.getRuntime().exec(new String[] {launcher, url});
        }
      } else {
        String launcher = preferences.get("launcher", null);
        if (launcher != null) {
          Runtime.getRuntime().exec(new String[] {launcher, url});
        } else {
          Base.logger.warning("Unspecified platform, no launcher available.");
        }
      }

    } catch (IOException e) {
      Base.showWarning("Could not open URL", "An error occurred while trying to open\n" + url, e);
    }
  }
Esempio n. 26
0
  /**
   * This is called upon return from entering a new file name. (that is, from either newCode or
   * renameCode after the prompt) This code is almost identical for both the newCode and renameCode
   * cases, so they're kept merged except for right in the middle where they diverge.
   */
  public void nameCode(String newName) {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // if renaming to the same thing as before, just ignore.
    // also ignoring case here, because i don't want to write
    // a bunch of special stuff for each platform
    // (osx is case insensitive but preserving, windows insensitive,
    // *nix is sensitive and preserving.. argh)
    if (renamingCode && newName.equalsIgnoreCase(current.name)) {
      // exit quietly for the 'rename' case.
      // if it's a 'new' then an error will occur down below
      return;
    }

    // don't allow blank names
    if (newName.trim().equals("")) {
      return;
    }

    if (newName.trim().equals(".gcode")) {
      return;
    }

    String newFilename = null;
    int newFlavor = 0;

    // separate into newName (no extension) and newFilename (with ext)
    // add .gcode to file if it has no extension
    if (newName.endsWith(".gcode")) {
      newFilename = newName;
      newName = newName.substring(0, newName.length() - 6);
      newFlavor = GCODE;

    } else {
      newFilename = newName + ".gcode";
      newFlavor = GCODE;
    }

    // dots are allowed for the .gcode and .java, but not in the name
    // make sure the user didn't name things poo.time.gcode
    // or something like that (nothing against poo time)
    if (newName.indexOf('.') != -1) {
      newFilename = newName + ".gcode";
    }

    // create the new file, new SketchCode object and load it
    File newFile = new File(folder, newFilename);
    if (newFile.exists()) { // yay! users will try anything
      Base.showMessage(
          "Nope",
          "A file named \""
              + newFile
              + "\" already exists\n"
              + "in \""
              + folder.getAbsolutePath()
              + "\"");
      return;
    }

    File newFileHidden = new File(folder, newFilename + ".x");
    if (newFileHidden.exists()) {
      // don't let them get away with it if they try to create something
      // with the same name as something hidden
      Base.showMessage(
          "No Way",
          "A hidden tab with the same name already exists.\n" + "Use \"Unhide\" to bring it back.");
      return;
    }

    if (renamingCode) {
      if (currentIndex == 0) {
        // get the new folder name/location
        File newFolder = new File(folder.getParentFile(), newName);
        if (newFolder.exists()) {
          Base.showWarning(
              "Cannot Rename",
              "Sorry, a sketch (or folder) named " + "\"" + newName + "\" already exists.",
              null);
          return;
        }

        // unfortunately this can't be a "save as" because that
        // only copies the sketch files and the data folder
        // however this *will* first save the sketch, then rename

        // first get the contents of the editor text area
        if (current.modified) {
          current.program = editor.getText();
          try {
            // save this new SketchCode
            current.save();
          } catch (Exception e) {
            Base.showWarning("Error", "Could not rename the sketch. (0)", e);
            return;
          }
        }

        if (!current.file.renameTo(newFile)) {
          Base.showWarning(
              "Error",
              "Could not rename \""
                  + current.file.getName()
                  + "\" to \""
                  + newFile.getName()
                  + "\"",
              null);
          return;
        }

        // save each of the other tabs because this is gonna be
        // re-opened
        try {
          for (int i = 1; i < codeCount; i++) {
            // if (code[i].modified) code[i].save();
            code[i].save();
          }
        } catch (Exception e) {
          Base.showWarning("Error", "Could not rename the sketch. (1)", e);
          return;
        }

        // now rename the sketch folder and re-open
        boolean success = folder.renameTo(newFolder);
        if (!success) {
          Base.showWarning("Error", "Could not rename the sketch. (2)", null);
          return;
        }
        // if successful, set base properties for the sketch

        File mainFile = new File(newFolder, newName + ".gcode");
        mainFilename = mainFile.getAbsolutePath();

        // having saved everything and renamed the folder and the main
        // .gcode,
        // use the editor to re-open the sketch to re-init state
        // (unfortunately this will kill positions for carets etc)
        editor.handleOpenUnchecked(
            mainFilename,
            currentIndex,
            editor.textarea.getSelectionStart(),
            editor.textarea.getSelectionEnd(),
            editor.textarea.getScrollPosition());

        // get the changes into the sketchbook menu
        // (re-enabled in 0115 to fix bug #332)
        // editor.sketchbook.rebuildMenus();

      } else { // else if something besides code[0]
        if (!current.file.renameTo(newFile)) {
          Base.showWarning(
              "Error",
              "Could not rename \""
                  + current.file.getName()
                  + "\" to \""
                  + newFile.getName()
                  + "\"",
              null);
          return;
        }

        // just reopen the class itself
        current.name = newName;
        current.file = newFile;
        current.flavor = newFlavor;
      }

    } else { // creating a new file
      try {
        newFile.createNewFile(); // TODO returns a boolean
      } catch (IOException e) {
        Base.showWarning(
            "Error",
            "Could not create the file \""
                + newFile
                + "\"\n"
                + "in \""
                + folder.getAbsolutePath()
                + "\"",
            e);
        return;
      }
      SketchCode newCode = new SketchCode(newName, newFile, newFlavor);
      insertCode(newCode);
    }

    // sort the entries
    sortCode();

    // set the new guy as current
    setCurrent(newName + flavorExtensionsShown[newFlavor]);

    // update the tabs
    // editor.header.repaint();

    editor.header.rebuild();

    // force the update on the mac?
    Toolkit.getDefaultToolkit().sync();
    // editor.header.getToolkit().sync();
  }
Esempio n. 27
0
  /** @param driver Needed for the Replicator-specific options */
  public PreferencesWindow(final MachineInterface machine) {
    super("Preferences");
    setResizable(true);

    Image icon = Base.getImage("images/icon.gif", this);
    setIconImage(icon);

    JTabbedPane prefTabs = new JTabbedPane();

    JPanel basic = new JPanel();

    //		Container content = this.getContentPane();
    Container content = basic;
    content.setLayout(new MigLayout("fill"));

    content.add(new JLabel("MainWindow font size: "), "split");
    fontSizeField = new JFormattedTextField(Base.getLocalFormat());
    fontSizeField.setColumns(4);
    content.add(fontSizeField);
    content.add(new JLabel("  (requires restart of ReplicatorG)"), "wrap");

    boolean checkTempDuringBuild = Base.preferences.getBoolean("build.monitor_temp", true);
    boolean displaySpeedWarning = Base.preferences.getBoolean("build.speed_warning", true);

    addCheckboxForPref(
        content, "Monitor temperature during builds", "build.monitor_temp", checkTempDuringBuild);
    addCheckboxForPref(
        content, "Display Accelerated Speed Warnings", "build.speed_warning", displaySpeedWarning);
    addCheckboxForPref(
        content, "Automatically connect to machine at startup", "replicatorg.autoconnect", true);
    addCheckboxForPref(
        content, "Show experimental machine profiles", "machine.showExperimental", false);
    addCheckboxForPref(
        content,
        "Review GCode for potential toolhead problems before building",
        "build.safetyChecks",
        true);
    addCheckboxForPref(
        content,
        "Break Z motion into separate moves (normally false)",
        "replicatorg.parser.breakzmoves",
        false);
    addCheckboxForPref(
        content, "Show starfield in model preview window", "ui.show_starfield", false);
    addCheckboxForPref(
        content, "Notifications in System tray", "ui.preferSystemTrayNotifications", false);
    addCheckboxForPref(
        content,
        "Automatically regenerate gcode when building from model view.",
        "build.autoGenerateGcode",
        true);
    addCheckboxForPref(
        content, "Use native avrdude for uploading code", "uploader.useNative", false);

    JPanel advanced = new JPanel();
    content = advanced;
    content.setLayout(new MigLayout("fill"));

    JButton modelColorButton;
    modelColorButton = new JButton("Choose model color");
    modelColorButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Note that this color is also defined in EditingModel.java
            Color modelColor = new Color(Base.preferences.getInt("ui.modelColor", -19635));
            modelColor = JColorChooser.showDialog(null, "Choose Model Color", modelColor);
            if (modelColor == null) return;

            Base.preferences.putInt("ui.modelColor", modelColor.getRGB());
            Base.getEditor().refreshPreviewPanel();
          }
        });
    modelColorButton.setVisible(true);
    content.add(modelColorButton, "split");

    JButton backgroundColorButton;
    backgroundColorButton = new JButton("Choose background color");
    backgroundColorButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            // Note that this color is also defined in EditingModel.java
            Color backgroundColor = new Color(Base.preferences.getInt("ui.backgroundColor", 0));
            backgroundColor =
                JColorChooser.showDialog(null, "Choose Background Color", backgroundColor);
            if (backgroundColor == null) return;

            Base.preferences.putInt("ui.backgroundColor", backgroundColor.getRGB());
            Base.getEditor().refreshPreviewPanel();
          }
        });
    backgroundColorButton.setVisible(true);
    content.add(backgroundColorButton, "wrap");

    content.add(new JLabel("Firmware update URL: "), "split");
    firmwareUpdateUrlField = new JTextField(34);
    content.add(firmwareUpdateUrlField, "growx, wrap");

    {
      JLabel arcResolutionLabel = new JLabel("Arc resolution (in mm): ");
      content.add(arcResolutionLabel, "split");
      double value = Base.preferences.getDouble("replicatorg.parser.curve_segment_mm", 1.0);
      JFormattedTextField arcResolutionField = new JFormattedTextField(Base.getLocalFormat());
      arcResolutionField.setValue(new Double(value));
      content.add(arcResolutionField);
      String arcResolutionHelp =
          "<html><small><em>"
              + "The arc resolution is the default segment length that the gcode parser will break arc codes <br>"
              + "like G2 and G3 into.  Drivers that natively handle arcs will ignore this setting."
              + "</em></small></html>";
      arcResolutionField.setToolTipText(arcResolutionHelp);
      arcResolutionLabel.setToolTipText(arcResolutionHelp);
      //			content.add(new JLabel(arcResolutionHelp),"growx,wrap");
      arcResolutionField.setColumns(10);
      arcResolutionField.addPropertyChangeListener(
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                try {
                  Double v = (Double) evt.getNewValue();
                  if (v == null) return;
                  Base.preferences.putDouble(
                      "replicatorg.parser.curve_segment_mm", v.doubleValue());
                } catch (ClassCastException cce) {
                  Base.logger.warning(
                      "Unexpected value type: " + evt.getNewValue().getClass().toString());
                }
              }
            }
          });
    }

    {
      JLabel sfTimeoutLabel = new JLabel("Skeinforge timeout: ");
      content.add(sfTimeoutLabel, "split, gap unrelated");
      int value = Base.preferences.getInt("replicatorg.skeinforge.timeout", -1);
      JFormattedTextField sfTimeoutField = new JFormattedTextField(Base.getLocalFormat());
      sfTimeoutField.setValue(new Integer(value));
      content.add(sfTimeoutField, "wrap 10px, growx");
      String sfTimeoutHelp =
          "<html><small><em>"
              + "The Skeinforge timeout is the number of seconds that replicatorg will wait while the<br>"
              + "Skeinforge preferences window is open. If you find that RepG freezes after editing profiles<br>"
              + "you can set this number greater than -1 (-1 means no timeout)."
              + "</em></small></html>";
      sfTimeoutField.setToolTipText(sfTimeoutHelp);
      sfTimeoutLabel.setToolTipText(sfTimeoutHelp);
      //			content.add(new JLabel(sfTimeoutHelp),"growx,wrap");
      sfTimeoutField.setColumns(10);
      sfTimeoutField.addPropertyChangeListener(
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                try {
                  Integer v = ((Number) evt.getNewValue()).intValue();
                  if (v == null) return;
                  Base.preferences.putInt("replicatorg.skeinforge.timeout", v.intValue());
                } catch (ClassCastException cce) {
                  Base.logger.warning(
                      "Unexpected value type: " + evt.getNewValue().getClass().toString());
                }
              }
            }
          });
    }

    {
      content.add(new JLabel("Debugging level (default INFO):"), "split");
      content.add(makeDebugLevelDropdown(), "wrap");

      final JCheckBox logCb = new JCheckBox("Log to file");
      logCb.setSelected(Base.preferences.getBoolean("replicatorg.useLogFile", false));
      content.add(logCb, "split");
      logCb.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              Base.preferences.putBoolean("replicatorg.useLogFile", logCb.isSelected());
            }
          });

      final JLabel logPathLabel = new JLabel("Log file name: ");
      content.add(logPathLabel, "split");
      logPathField = new JTextField(34);
      content.add(logPathField, "growx, wrap 10px");
      logPathField.setEnabled(logCb.isSelected());
      logPathLabel.setEnabled(logCb.isSelected());

      logCb.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              JCheckBox box = (JCheckBox) e.getSource();
              logPathField.setEnabled(box.isSelected());
              logPathLabel.setEnabled(box.isSelected());
            }
          });
    }

    {
      final int defaultTemp = 75;
      final String tooltipGeneral =
          "When enabled, starting all builds heats components to this temperature";
      final String tooltipHead = "Set preheat temperature for the specified toolhead";
      final String tooltipPlatform = "Set preheat temperature for the build platfom";

      final JCheckBox preheatCb = new JCheckBox("Preheat builds");
      preheatCb.setToolTipText(tooltipGeneral);
      content.add(preheatCb, "split");

      preheatCb.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
              Base.preferences.putBoolean("build.doPreheat", preheatCb.isSelected());
            }
          });
      preheatCb.setSelected(Base.preferences.getBoolean("build.doPreheat", false));

      final JLabel t0Label = new JLabel("Toolhead Right: ");
      final JLabel t1Label = new JLabel("Toolhead Left: ");
      final JLabel pLabel = new JLabel("Platform: ");

      Integer t0Value = Base.preferences.getInt("build.preheatTool0", defaultTemp);
      Integer t1Value = Base.preferences.getInt("build.preheatTool1", defaultTemp);
      Integer pValue = Base.preferences.getInt("build.preheatPlatform", defaultTemp);

      final JFormattedTextField t0Field = new JFormattedTextField(Base.getLocalFormat());
      final JFormattedTextField t1Field = new JFormattedTextField(Base.getLocalFormat());
      final JFormattedTextField pField = new JFormattedTextField(Base.getLocalFormat());

      t0Field.setToolTipText(tooltipHead);
      t0Label.setToolTipText(tooltipHead);
      t1Field.setToolTipText(tooltipHead);
      t1Label.setToolTipText(tooltipHead);
      pField.setToolTipText(tooltipPlatform);
      pLabel.setToolTipText(tooltipPlatform);

      t0Field.setValue(t0Value);
      t1Field.setValue(t1Value);
      pField.setValue(pValue);

      // let's avoid creating too many Anon. inner Listeners, also is fewer lines (and just as
      // clear)!
      PropertyChangeListener p =
          new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
              if (evt.getPropertyName() == "value") {
                double target;
                if (evt.getSource() == t0Field) {
                  target = ((Number) t0Field.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit", 200.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatTool0", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatTool0", (int) target);
                } else if (evt.getSource() == t1Field) {
                  target = ((Number) t1Field.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit", 200.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatTool1", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatTool1", (int) target);
                } else if (evt.getSource() == pField) {
                  target = ((Number) pField.getValue()).doubleValue();
                  target = confirmTemperature(target, "temperature.acceptedLimit.bed", 110.0);
                  if (target == Double.MIN_VALUE) {
                    t0Field.setValue(Base.preferences.getInt("build.preheatPlatform", defaultTemp));
                    return;
                  }
                  Base.preferences.putInt("build.preheatPlatform", (int) target);
                }
              }
            }
          };

      t0Field.addPropertyChangeListener(p);
      t1Field.addPropertyChangeListener(p);
      pField.addPropertyChangeListener(p);

      content.add(t0Label, "split, gap 20px");
      content.add(t0Field, "split, growx");
      content.add(t1Label, "split, gap unrelated");
      content.add(t1Field, "split, growx");
      content.add(pLabel, "split, gap unrelated");
      content.add(pField, "split, growx, wrap 10px");
    }

    {
      JButton b = new JButton("Select Python interpreter...");
      content.add(b, "spanx,wrap 10px");
      b.addActionListener(
          new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              SwingPythonSelector sps = new SwingPythonSelector(PreferencesWindow.this);
              String path = sps.selectFreeformPath();
              if (path != null) {
                PythonUtils.setPythonPath(path);
              }
            }
          });
    }

    addInitialFilePrefs(content);

    prefTabs.add(basic, "Basic");
    prefTabs.add(advanced, "Advanced");

    content = getContentPane();
    content.setLayout(new MigLayout());

    content.add(prefTabs, "wrap");

    JButton allPrefs = new JButton("View Preferences Table");
    content.add(allPrefs, "split");
    allPrefs.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            JFrame advancedPrefs = new AdvancedPrefs();
            advancedPrefs.setVisible(true);
          }
        });

    // Also available as a menu item in the main gui.
    JButton delPrefs = new JButton("Reset all preferences");
    content.add(delPrefs);
    delPrefs.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            editor.resetPreferences();
          }
        });

    JButton button;
    button = new JButton("Close");
    button.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            applyFrame();
            dispose();
          }
        });
    content.add(button, "tag ok");

    showCurrentSettings();

    // closing the window is same as hitting cancel button
    addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            dispose();
          }
        });

    ActionListener disposer =
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            dispose();
          }
        };
    Base.registerWindowCloseKeys(getRootPane(), disposer);

    pack();
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    setLocation((screen.width - getWidth()) / 2, (screen.height - getHeight()) / 2);

    // handle window closing commands for ctrl/cmd-W or hitting ESC.

    getContentPane()
        .addKeyListener(
            new KeyAdapter() {
              public void keyPressed(KeyEvent e) {
                KeyStroke wc = MainWindow.WINDOW_CLOSE_KEYSTROKE;
                if ((e.getKeyCode() == KeyEvent.VK_ESCAPE)
                    || (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
                  dispose();
                }
              }
            });
  }
Esempio n. 28
0
  public static void main(String args[]) {

    // make sure that this is running on java 1.5 or better.
    if (Base.javaVersion < 1.5f) {
      Base.quitWithError(
          "Need to install Java 1.5",
          "This version of ReplicatorG requires\n"
              + "Java 1.5 or later to run properly.\n"
              + "Please visit java.com to upgrade.",
          null);
    }

    if (Base.isMacOS()) {
      // Default to sun's XML parser, PLEASE.  Some apps are installing some janky-ass xerces.
      System.setProperty(
          "javax.xml.parsers.DocumentBuilderFactory",
          "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
      System.setProperty("com.apple.mrj.application.apple.menu.about.name", "ReplicatorG");
    }

    // parse command line input
    for (int i = 0; i < args.length; i++) {
      // grab any opened file from the command line
      if (supportedExtension(args[i])) {
        Base.openedAtStartup = args[i];
      }

      // Allow for [--debug] [DEBUGLEVEL]
      if (args[i].equals("--debug")) {
        int debugLevelArg = 2;
        if ((i + 1) < args.length) {
          try {
            debugLevelArg = Integer.parseInt(args[i + 1]);
          } catch (NumberFormatException e) {
          }
          ;
        }
        if (debugLevelArg == 0) {
          logger.setLevel(Level.INFO);
          logger.info("Debug level is 'INFO'");
        } else if (debugLevelArg == 1) {
          logger.setLevel(Level.FINE);
          logger.info("Debug level is 'FINE'");
        } else if (debugLevelArg == 2) {
          logger.setLevel(Level.FINER);
          logger.info("Debug level is 'FINER'");
        } else if (debugLevelArg == 3) {
          logger.setLevel(Level.FINEST);
          logger.info("Debug level is 'FINEST'");
        } else if (debugLevelArg >= 4) {
          logger.setLevel(Level.ALL);
          logger.info("Debug level is 'ALL'");
        }
      } else if (args[i].startsWith("-")) {
        System.out.println("Usage: ./replicatorg [[--debug] [DEBUGLEVEL]] [filename.stl]");
        System.exit(1);
      }
    }

    // Warn about read-only directories
    {
      File userDir = getUserDirectory();
      String header = null;
      if (!userDir.exists()) header = new String("Unable to create user directory");
      else if (!userDir.canWrite()) header = new String("Unable to write to user directory");
      else if (!userDir.isDirectory()) header = new String("User directory must be a directory");
      if (header != null) {
        Base.showMessage(
            header,
            "<html><body>ReplicatorG can not write to the directory "
                + userDir.getAbsolutePath()
                + ".<br>"
                + "Some functions of ReplicatorG, like toolpath generation and firmware updates,<br>"
                + "require ReplicatorG to write data to this directory.  You should end this<br>"
                + "session, change the permissions on this directory, and start again.");
      }
    }

    // Use the default system proxy settings
    System.setProperty("java.net.useSystemProxies", "true");
    // Use antialiasing implicitly
    System.setProperty("j3d.implicitAntialiasing", "true");

    // Start the firmware check thread.
    FirmwareUploader.checkFirmware();

    // MAC OS X ONLY:
    // register a temporary/early version of the mrj open document handler,
    // because the event may be lost (sometimes, not always) by the time
    // that MainWindow is properly constructed.
    MRJOpenDocumentHandler startupOpen =
        new MRJOpenDocumentHandler() {
          public void handleOpenFile(File file) {
            // this will only get set once.. later will be handled
            // by the MainWindow version of this fella
            if (Base.openedAtStartup == null) {
              Base.openedAtStartup = file.getAbsolutePath();
            }
          }
        };
    MRJApplicationUtils.registerOpenDocumentHandler(startupOpen);

    // Create the new application "Base" class.
    new Base();
  }
Esempio n. 29
0
  public Base() {
    // set the look and feel before opening the window
    try {
      if (Base.isMacOS()) {
        // Only override the UI's necessary for ColorChooser and
        // FileChooser:
        Set<Object> includes = new HashSet<Object>();
        includes.add("ColorChooser");
        includes.add("FileChooser");
        includes.add("Component");
        includes.add("Browser");
        includes.add("Tree");
        includes.add("SplitPane");
        QuaquaManager.setIncludedUIs(includes);

        // set the Quaqua Look and Feel in the UIManager
        UIManager.setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel");
        System.setProperty("apple.laf.useScreenMenuBar", "true");

      } else if (Base.isLinux()) {
        // For 0120, trying out the gtk+ look and feel as the default.
        // This is available in Java 1.4.2 and later, and it can't
        // possibly
        // be any worse than Metal. (Ocean might also work, but that's
        // for
        // Java 1.5, and we aren't going there yet)
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");

      } else {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    // use native popups so they don't look so crappy on osx
    JPopupMenu.setDefaultLightWeightPopupEnabled(false);

    SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            // build the editor object
            editor = new MainWindow();
            // Get sizing preferences. This is an issue of contention; let's look at how
            // other programs decide how to size themselves.
            editor.restorePreferences();
            // add shutdown hook to store preferences
            Runtime.getRuntime()
                .addShutdownHook(
                    new Thread("Shutdown Hook") {
                      private final MainWindow w = editor;

                      public void run() {
                        w.onShutdown();
                      }
                    });

            boolean autoconnect = Base.preferences.getBoolean("replicatorg.autoconnect", true);
            String machineName = preferences.get("machine.name", null);

            editor.loadMachine(machineName, autoconnect);

            // show the window
            editor.setVisible(true);
            UpdateChecker.checkLatestVersion(editor);
          }
        });

    if (logger.isLoggable(Level.FINE)) {
      logger.fine(
          "OS: "
              + System.getProperty("os.name")
              + " "
              + System.getProperty("os.version")
              + " ("
              + System.getProperty("os.arch")
              + ")");
      logger.fine(
          "JVM: "
              + System.getProperty("java.version")
              + " "
              + System.getProperty("java.vm.name")
              + " ("
              + System.getProperty("java.vm.version")
              + " "
              + System.getProperty("java.vendor")
              + ")");
    }
  }
Esempio n. 30
0
  /** Remove a piece of code from the sketch and from the disk. */
  public void deleteCode() {
    // make sure the user didn't hide the sketch folder
    ensureExistence();

    // if read-only, give an error
    if (isReadOnly()) {
      // if the files are read-only, need to first do a "save as".
      Base.showMessage(
          "Sketch is Read-Only",
          "Some files are marked \"read-only\", so you'll\n"
              + "need to re-save the sketch in another location,\n"
              + "and try again.");
      return;
    }

    // confirm deletion with user, yes/no
    Object[] options = {"OK", "Cancel"};
    String prompt =
        (currentIndex == 0)
            ? "Are you sure you want to delete this sketch?"
            : "Are you sure you want to delete \""
                + current.name
                + flavorExtensionsShown[current.flavor]
                + "\"?";
    int result =
        JOptionPane.showOptionDialog(
            editor,
            prompt,
            "Delete",
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null,
            options,
            options[0]);
    if (result == JOptionPane.YES_OPTION) {
      if (currentIndex == 0) {
        // need to unset all the modified flags, otherwise tries
        // to do a save on the handleNew()

        // delete the entire sketch
        Base.removeDir(folder);

        // get the changes into the sketchbook menu
        // sketchbook.rebuildMenus();

        // make a new sketch, and i think this will rebuild the sketch
        // menu
        editor.handleNewUnchecked();

      } else {
        // delete the file
        if (!current.file.delete()) {
          Base.showMessage("Couldn't do it", "Could not delete \"" + current.name + "\".");
          return;
        }

        // remove code from the list
        removeCode(current);

        // just set current tab to the main tab
        setCurrent(0);

        // update the tabs
        editor.header.repaint();
      }
    }
  }