Logo Search packages:      
Sourcecode: ecasound version File versions  Download package

void ECA_CONTROL::edit_chainsetup ( void   )

Spawns an external editor for editing selected chainsetup

require: is_selected() connected_chainsetup() != selected_chainsetup()

Definition at line 249 of file eca-control-objects.cpp.

References connect_chainsetup(), connected_chainsetup(), TEMPORARY_FILE_DIRECTORY::create_filename(), disconnect_chainsetup(), is_connected(), is_running(), is_selected(), is_valid(), TEMPORARY_FILE_DIRECTORY::is_valid(), remove_chainsetup(), TEMPORARY_FILE_DIRECTORY::reserve_directory(), resource_value(), selected_chainsetup(), and start().

{
  // --------
  DBC_REQUIRE(selected_chainsetup().empty() != true);
  // --------

  /* 1. check which editor to use (and exit if none 
   *    defined) */
  string editori = "";
  string use_getenv =
    resource_value("ext-cmd-text-editor-use-getenv");
  
  if (use_getenv.size() == 0 ||
      use_getenv == "true") {
    /* note: as specified in ecasoundrc(5), we should 
     *       default to 'true' */
    if (std::getenv("EDITOR") != 0) {
      editori = std::getenv("EDITOR");
    }
  }
  if (editori == "") 
    editori = resource_value("ext-cmd-text-editor");

  if (editori == "") {
    ECA_LOG_MSG(ECA_LOGGER::info,
            "ERROR: Cannot edit, no text editor specified/available. See ecasoundrc(5) man page and the 'ext-cmd-text-editor' configuration variable.");
    return;
  }
  
  /* 2. detect hot-swap */
  bool hot_swap = false;
  bool restart = false;
  if (connected_chainsetup() == selected_chainsetup()) {
    hot_swap = true;
    if (is_running()) restart = true;
  }

  /* 3. store runtime state of the old chainsetup */
  string origname = selected_chainsetup_repp->name();
  string origfilename = selected_chainsetup_repp->filename();
  SAMPLE_SPECS::sample_pos_t origpos = selected_chainsetup_repp->position_in_samples();

  /* 4. create a safely accessible temporary filename */
  TEMPORARY_FILE_DIRECTORY tempfile_dir_rep;
  string tmpdir ("ecasound-");
  char* tmp_p = std::getenv("USER");
  if (tmp_p != NULL) {
    tmpdir += string(tmp_p);
    tempfile_dir_rep.reserve_directory(tmpdir);
  }
  if (tempfile_dir_rep.is_valid() != true) {
    ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: Unable to create temporary directory \"" + tmpdir + "\".");
    return;
  }
  string filename = tempfile_dir_rep.create_filename("cs-edit-tmp", ".ecs");

  /* 5. save selected chainsetup to the temp file */
  if (hot_swap == true)
    session_repp->connected_chainsetup_repp->set_name("cs-edit-temp");

  save_chainsetup(filename);

  if (hot_swap == true)
    session_repp->connected_chainsetup_repp->set_name(origname);
  else
    remove_chainsetup();

  /* 6. fork an external text editor */

  // FIXME: we should drop priviledge-level here (at least if root)!
  editori += " " + filename;
  int res = ::system(editori.c_str());

  if (res == 127 || res == -1) {
    ECA_LOG_MSG(ECA_LOGGER::info, "Can't edit; unable to open file in text editor \"" + string(editori.c_str()) + "\".");

  }
  else {
    /* 7. reload the edited chainsetup and reset runtime state */
    load_chainsetup(filename);

    if (is_selected() != true) {
      ECA_LOG_MSG(ECA_LOGGER::info, 
              std::string("Unable to parse chainsetup, keeping the temporary file ") + filename);
    }
    else {
      remove(filename.c_str());
      if (origfilename.empty() != true) {
      set_chainsetup_filename(origfilename);
      }

      if (selected_chainsetup_repp)
      selected_chainsetup_repp->seek_position_in_samples(origpos);

      if (hot_swap == true) {
      /* 7.1 disconnect the chainsetup to be replaced */
      disconnect_chainsetup();
      
      /* 7.2 try to connect the edited chainsetup */
      select_chainsetup("cs-edit-temp");
      if (is_valid() == true) {
        connect_chainsetup(0);
        /* should succeed as is_valid() is true */
        DBC_CHECK(is_connected() == true);
        if (is_connected() == true) {
          if (restart == true) {
            DBC_CHECK(is_running() != true);
            start();
          }
        }
      }

      /* 7.3 if connecting the modified chainsetup fails */
      if (is_connected() != true) {
        ECA_LOG_MSG(ECA_LOGGER::info, "Can't connect; edited chainsetup is not valid.");
      }
      
      /* 7.4 remove the old chainsetup */
      select_chainsetup(origname);
      remove_chainsetup();
      select_chainsetup("cs-edit-temp");
      selected_chainsetup_repp->set_name(origname);
      }
    }
  }
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index