DefinitionNode *DefinitionNode::findByPath(const string &path) const { if (path.empty()) { return NULL; } else if (path[0] == '/') { if (path.length() == 1) { return root; } else if (root == this) { return findByPath(path.substr(1)); } else { return root->findByPath(path); } } else { size_t seppos = path.find("/"); string child_name = (seppos == string::npos) ? path : path.substr(0, seppos); DefinitionNode *child = findChildByName(child_name); if (child) { if (seppos == string::npos) { return child; } else { return child->findByPath(path.substr(seppos + 1)); } } else { return NULL; } } }
QStringList RObjectList::detachPackages (const QStringList &packages, RCommandChain *chain, RKProgressControl* control) { RK_TRACE (OBJECTS); QStringList remove; QStringList reject; for (int i = 0; i < packages.size(); ++i) { QString shortname = packages[i]; shortname.remove ("package:"); if (RKSettingsModuleRPackages::essentialPackages ().contains (shortname)) { reject.append (i18n ("Did not unload package %1. It is required in RKWard. If you really want to do this, do so on the R Console.", shortname)); } else if (!findChildByName (packages[i])) { RK_ASSERT (false); reject.append (i18n ("Package %1 appears not to have been loaded", shortname)); } else { remove.append (packages[i]); } } for (int i = 0; i < remove.size (); ++i) { RCommand *command = new RCommand ("detach (" + rQuote (remove[i]) + ')', RCommand::App | RCommand::ObjectListUpdate); if (control) control->addRCommand (command); RKGlobals::rInterface()->issueCommand (command, chain); } return reject; }
void RObjectList::updateEnvironments (const QStringList &_env_names, bool force_globalenv_update) { RK_TRACE (OBJECTS); RObjectMap newchildmap; QStringList env_names = _env_names; if (!env_names.isEmpty ()) { QString dummy = env_names.takeFirst (); RK_ASSERT (dummy == ".GlobalEnv"); if (force_globalenv_update) { // for now, we only update the .GlobalEnv. All others we assume to be static getGlobalEnv ()->updateFromR (update_chain); } } else { RK_ASSERT (!env_names.isEmpty ()); } // find which items are new, and copy the old ones for (int i = 0; i < env_names.count (); ++i) { QString name = env_names[i]; RObject *obj = findChildByName (name); if (obj && (i > 0) && (env_names.lastIndexOf (name, i-1) > -1)) { // duplicate environment names can happen (e.g. if a data.frame is attached multiple times) obj = 0; // only copy the old item once } if (!obj) { obj = createTopLevelEnvironment (name); RKGlobals::tracker ()->beginAddObject (obj, this, i); childmap.insert (i, obj); RKGlobals::tracker ()->endAddObject (obj, this, i); } newchildmap.insert (i, obj); } // check which envs have been removed or changed position for (int i = 0; i < childmap.size (); ++i) { // do *not* cache the childmap.size ()! We may change it in the loop. RObject *obj = childmap[i]; int new_pos = newchildmap.indexOf (obj); if (new_pos < 0) { // environment is gone RK_DEBUG (OBJECTS, DL_INFO, "removing toplevel environment %s from list", obj->getShortName ().toLatin1 ().data ()); if (RKGlobals::tracker ()->removeObject (obj, 0, true)) --i; else (newchildmap.insert (i, obj)); } else if (new_pos != i) { // this call is rather expensive, all in all, but fortunately called very rarely moveChild (obj, i, new_pos); } } RK_DO (RK_ASSERT (childmap == newchildmap), OBJECTS, DL_DEBUG); // this is an expensive assert, hence wrapping it inside RK_DO }
void DefinitionNode::load(PackStream *stream) { int children_count; stream->read(&children_count); for (int i = 0; i < children_count; i++) { string child_name = stream->readString(); int child_size; stream->read(&child_size); DefinitionNode *child = findChildByName(child_name); if (child) { // TODO type check child->load(stream); } else { // TODO Ask subclass if it can instanciate a child // Else skip length of unknown child stream->skipBytes(child_size); Logs::warning("Definition") << "Skipped unknown child '" << child_name << "'" << endl; } } }