RKPluginSpinBox::RKPluginSpinBox (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget) : RKComponent (parent_component, parent_widget) { RK_TRACE (PLUGIN); // get xml-helper XMLHelper *xml = XMLHelper::getStaticHelper (); // first question: int or real intmode = (xml->getMultiChoiceAttribute (element, "type", "integer;real", 1, DL_INFO) == 0); // create and add properties addChild ("int", intvalue = new RKComponentPropertyInt (this, intmode, 0)); intvalue->setInternal (true); addChild ("real", realvalue = new RKComponentPropertyDouble (this, !intmode, 0)); // layout and label QVBoxLayout *vbox = new QVBoxLayout (this); vbox->setContentsMargins (0, 0, 0, 0); QLabel *label = new QLabel (xml->getStringAttribute (element, "label", i18n ("Enter value:"), DL_WARNING), this); vbox->addWidget (label); // create spinbox and read settings spinbox = new RKSpinBox (this); if (!intmode) { double min = xml->getDoubleAttribute (element, "min", -FLT_MAX, DL_INFO); double max = xml->getDoubleAttribute (element, "max", FLT_MAX, DL_INFO); double initial = xml->getDoubleAttribute (element, "initial", min, DL_INFO); int default_precision = xml->getIntAttribute (element, "default_precision", 2, DL_INFO); int max_precision = xml->getIntAttribute (element, "max_precision", 8, DL_INFO); spinbox->setRealMode (min, max, initial, default_precision, max_precision); realvalue->setMin (min); realvalue->setMax (max); realvalue->setPrecision (default_precision); } else { int min = xml->getIntAttribute (element, "min", INT_MIN, DL_INFO); int max = xml->getIntAttribute (element, "max", INT_MAX, DL_INFO); int initial = xml->getIntAttribute (element, "initial", min, DL_INFO); spinbox->setIntMode (min, max, initial); intvalue->setMin (min); intvalue->setMax (max); } // connect connect (spinbox, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int))); connect (intvalue, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (valueChanged (RKComponentPropertyBase *))); connect (realvalue, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (valueChanged (RKComponentPropertyBase *))); updating = false; // finish layout vbox->addWidget (spinbox); vbox->addStretch (1); // make sure label remains attached to spinbox if (xml->getStringAttribute (element, "size", "normal", DL_INFO) == "small") { spinbox->setFixedWidth (100); } // initialize valueChanged (1); }
RKPluginBrowser::RKPluginBrowser (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget) : RKComponent (parent_component, parent_widget) { RK_TRACE (PLUGIN); // get xml-helper XMLHelper *xml = XMLHelper::getStaticHelper (); // create and add property addChild ("selection", selection = new RKComponentPropertyBase (this, true)); connect (selection, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (textChanged (RKComponentPropertyBase *))); setRequired (xml->getBoolAttribute (element, "required", true, DL_INFO)); connect (requirednessProperty (), SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (requirednessChanged(RKComponentPropertyBase*))); QVBoxLayout *vbox = new QVBoxLayout (this, RKGlobals::spacingHint ()); int intmode = xml->getMultiChoiceAttribute (element, "type", "file;dir;savefile", 0, DL_INFO); GetFileNameWidget::FileType mode; if (intmode == 0) { mode = GetFileNameWidget::ExistingFile; } else if (intmode == 0) { mode = GetFileNameWidget::ExistingDirectory; } else { mode = GetFileNameWidget::SaveFile; } selector = new GetFileNameWidget (this, mode, xml->getStringAttribute (element, "label", i18n ("Enter filename"), DL_INFO), i18n ("Select"), xml->getStringAttribute (element, "initial", QString::null, DL_INFO)); selector->setFilter (xml->getStringAttribute (element, "filter", QString::null, DL_INFO)); connect (selector, SIGNAL (locationChanged ()), SLOT (textChanged ())); vbox->addWidget (selector); // initialize updating = false; textChanged (); }
int RKComponentMap::addPluginMap (const QString& plugin_map_file) { RK_TRACE (PLUGIN); XMLHelper* xml = XMLHelper::getStaticHelper (); QDomElement element; XMLChildList list; QDomElement document_element = xml->openXMLFile (plugin_map_file, DL_ERROR); if (xml->highestError () >= DL_ERROR) return (0); QString prefix = QFileInfo (plugin_map_file).dirPath (true) + "/" + xml->getStringAttribute (document_element, "base_prefix", QString::null, DL_INFO); QString cnamespace = xml->getStringAttribute (document_element, "namespace", "rkward", DL_INFO) + "::"; // step 1: create (list of) components element = xml->getChildElement (document_element, "components", DL_INFO); list = xml->getChildElements (element, "component", DL_INFO); for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) { QString filename = prefix + xml->getStringAttribute((*it), "file", QString::null, DL_WARNING); QString id = cnamespace + xml->getStringAttribute((*it), "id", QString::null, DL_WARNING); int type = xml->getMultiChoiceAttribute ((*it), "type", "standard", 0, DL_WARNING); QString label = xml->getStringAttribute ((*it), "label", i18n ("(no label)"), DL_WARNING); if (components.contains (id)) { RK_DO (qDebug ("RKComponentMap already contains a component with id \"%s\". Ignoring second entry.", id.latin1 ()), PLUGIN, DL_WARNING); } else if (!QFileInfo (filename).isReadable ()) { RK_DO (qDebug ("Specified file '%s' for component id \"%s\" does not exist or is not readable. Ignoring.", filename.latin1 (), id.latin1 ()), PLUGIN, DL_ERROR); } else { components.insert (id, RKComponentHandle::createComponentHandle (filename, (RKComponentType) type, id, label)); } } // step 2: create / insert into menus QDomElement xmlgui_menubar_elem = xml->getChildElement (xmlguiBuildDocument ().documentElement (), "MenuBar", DL_ERROR); element = xml->getChildElement (document_element, "hierarchy", DL_INFO); list = xml->getChildElements (element, "menu", DL_INFO); int counter = 0; for (XMLChildList::const_iterator it=list.begin (); it != list.end (); ++it) { counter += addSubMenu (xmlgui_menubar_elem, (*it), cnamespace); } // step 3: included files QStringList includelist; list = xml->getChildElements (document_element, "include", DL_INFO); for (XMLChildList::const_iterator it=list.constBegin (); it != list.constEnd (); ++it) { QString file = prefix + xml->getStringAttribute (*it, "file", QString::null, DL_ERROR); if (QFileInfo (file).isReadable ()) { includelist.append (file); } else { RK_DO (qDebug ("Specified include file '%s' does not exist or is not readable. Ignoring.", file.latin1 ()), PLUGIN, DL_ERROR); } } for (QStringList::const_iterator it = includelist.constBegin (); it != includelist.constEnd (); ++it) { counter += addPluginMap (*it); } return counter; }
RKInput::RKInput (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget) : RKComponent (parent_component, parent_widget) { RK_TRACE (PLUGIN); textedit = 0; lineedit = 0; // get xml-helper XMLHelper *xml = parent_component->xmlHelper (); // create and add property addChild ("text", text = new RKComponentPropertyBase (this, false)); connect (text, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (textChanged(RKComponentPropertyBase*))); setRequired (xml->getBoolAttribute (element, "required", false, DL_INFO)); connect (requirednessProperty (), SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (requirednessChanged(RKComponentPropertyBase*))); // do all the layouting QVBoxLayout *vbox = new QVBoxLayout (this); vbox->setContentsMargins (0, 0, 0, 0); label_string = xml->i18nStringAttribute (element, "label", i18n ("Enter text"), DL_INFO); if (!label_string.isEmpty ()) { QLabel *label = new QLabel (label_string, this); vbox->addWidget (label); } int size = xml->getMultiChoiceAttribute (element, "size", "small;medium;large", 1, DL_INFO); if (size == 2) { textedit = new QTextEdit (this); QFontMetrics fm = QFontMetrics (textedit->currentFont ()); int lheight = fm.lineSpacing (); int margin = fm.descent () + 2; textedit->setMinimumSize (250, lheight * 4 + margin); vbox->addWidget (textedit); connect (textedit, SIGNAL (textChanged()), SLOT (textChanged())); } else { lineedit = new QLineEdit (this); vbox->addWidget (lineedit); connect (lineedit, SIGNAL (textChanged(QString)), SLOT (textChanged(QString))); } vbox->addStretch (1); // to keep the label attached // initialize updating = false; // DO NOT replace "" with QString (), here! it is important, that this is actually an empty string, not a null string. text->setValue (xml->getStringAttribute (element, "initial", "", DL_INFO)); }
RKMatrixInput::RKMatrixInput (const QDomElement& element, RKComponent* parent_component, QWidget* parent_widget) : RKComponent (parent_component, parent_widget) { RK_TRACE (PLUGIN); is_valid = true; // get xml-helper XMLHelper *xml = parent_component->xmlHelper (); // create layout QVBoxLayout *vbox = new QVBoxLayout (this); vbox->setContentsMargins (0, 0, 0, 0); QLabel *label = new QLabel (xml->i18nStringAttribute (element, "label", i18n ("Enter data:"), DL_INFO), this); vbox->addWidget (label); display = new RKTableView (this); vbox->addWidget (display); mode = static_cast<Mode> (xml->getMultiChoiceAttribute (element, "mode", "integer;real;string", 1, DL_WARNING)); if (mode == Integer) { min = xml->getIntAttribute (element, "min", INT_MIN, DL_INFO) - .1; // we'll only allow ints anyway. Make sure not to run into floating point precision issues. max = xml->getIntAttribute (element, "max", INT_MAX, DL_INFO) + .1; } else if (mode == Real) { min = xml->getDoubleAttribute (element, "min", -FLT_MAX, DL_INFO); max = xml->getDoubleAttribute (element, "max", FLT_MAX, DL_INFO); } else { min = -FLT_MAX; max = FLT_MAX; } min_rows = xml->getIntAttribute (element, "min_rows", 0, DL_INFO); min_columns = xml->getIntAttribute (element, "min_columns", 0, DL_INFO); // Note: string type matrix allows missings, implicitly (treating them as empty strings) allow_missings = xml->getBoolAttribute (element, "allow_missings", false, DL_INFO); if (mode == String) allow_missings = true; allow_user_resize_columns = xml->getBoolAttribute (element, "allow_user_resize_columns", true, DL_INFO); allow_user_resize_rows = xml->getBoolAttribute (element, "allow_user_resize_rows", true, DL_INFO); trailing_rows = allow_user_resize_rows ? 1 : 0; trailing_columns = allow_user_resize_columns ? 1 : 0; row_count = new RKComponentPropertyInt (this, false, xml->getIntAttribute (element, "rows", qMax (2, min_rows), DL_INFO)); column_count = new RKComponentPropertyInt (this, false, xml->getIntAttribute (element, "columns", qMax (2, min_columns), DL_INFO)); tsv_data = new RKComponentPropertyBase (this, false); row_count->setInternal (true); addChild ("rows", row_count); column_count->setInternal (true); addChild ("columns", column_count); addChild ("tsv", tsv_data); connect (row_count, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (dimensionPropertyChanged(RKComponentPropertyBase*))); connect (column_count, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (dimensionPropertyChanged(RKComponentPropertyBase*))); connect (tsv_data, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (tsvPropertyChanged())); updating_tsv_data = false; model = new RKMatrixInputModel (this); QString headers = xml->getStringAttribute (element, "horiz_headers", QString (), DL_INFO); if (!headers.isEmpty ()) model->horiz_header = headers.split (';'); else if (!headers.isNull ()) display->horizontalHeader ()->hide (); // attribute explicitly set to "" headers = xml->getStringAttribute (element, "vert_headers", QString (), DL_INFO); if (!headers.isEmpty ()) model->vert_header = headers.split (';'); else if (!headers.isNull ()) display->verticalHeader ()->hide (); updateAll (); display->setModel (model); display->setAlternatingRowColors (true); if (xml->getBoolAttribute (element, "fixed_width", false, DL_INFO)) { display->horizontalHeader ()->setStretchLastSection (true); } if (xml->getBoolAttribute (element, "fixed_height", false, DL_INFO)) { int max_row = row_count->intValue () - 1; display->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); display->setFixedHeight (display->horizontalHeader ()->height () + display->rowViewportPosition (max_row) + display->rowHeight (max_row)); } // define standard actions KAction *cut = KStandardAction::cut (this, SLOT (cut()), this); display->addAction (cut); KAction *copy = KStandardAction::copy (this, SLOT (copy()), this); display->addAction (copy); KAction *paste = KStandardAction::paste (this, SLOT (paste()), this); display->addAction (paste); display->setContextMenuPolicy (Qt::ActionsContextMenu); display->setRKItemDelegate (new RKItemDelegate (display, model, true)); connect (display, SIGNAL (blankSelectionRequest()), this, SLOT (clearSelectedCells())); }
RKPreviewBox::RKPreviewBox (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget) : RKComponent (parent_component, parent_widget) { RK_TRACE (PLUGIN); prior_preview_done = true; new_preview_pending = false; // get xml-helper XMLHelper *xml = parent_component->xmlHelper (); preview_mode = (PreviewMode) xml->getMultiChoiceAttribute (element, "mode", "plot;data;output;custom", 0, DL_INFO); placement = (PreviewPlacement) xml->getMultiChoiceAttribute (element, "placement", "default;attached;detached;docked", 0, DL_INFO); if (placement == DefaultPreview) placement = DockedPreview; preview_active = xml->getBoolAttribute (element, "active", false, DL_INFO); idprop = RObject::rQuote (QString ().sprintf ("%p", this)); // create and add property addChild ("state", state = new RKComponentPropertyBool (this, true, preview_active, "active", "inactive")); state->setInternal (true); // restoring this does not make sense. connect (state, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (changedState(RKComponentPropertyBase*))); // create checkbox QVBoxLayout *vbox = new QVBoxLayout (this); vbox->setContentsMargins (0, 0, 0, 0); toggle_preview_box = new QCheckBox (xml->i18nStringAttribute (element, "label", i18n ("Preview"), DL_INFO), this); vbox->addWidget (toggle_preview_box); toggle_preview_box->setChecked (preview_active); connect (toggle_preview_box, SIGNAL (stateChanged(int)), this, SLOT (changedState(int))); // status label status_label = new QLabel (QString (), this); status_label->setWordWrap (true); vbox->addWidget (status_label); // prepare placement placement_command = ".rk.with.window.hints ({"; placement_end = "\n}, "; if (placement == AttachedPreview) placement_end.append ("\"attached\""); else if (placement == DetachedPreview) placement_end.append ("\"detached\""); else placement_end.append ("\"\""); placement_end.append (", " + RObject::rQuote (idprop) + ", style=\"preview\")"); if (placement == DockedPreview) { RKStandardComponent *uicomp = topmostStandardComponent (); if (uicomp) { uicomp->addDockedPreview (state, toggle_preview_box->text (), idprop); if (preview_mode == OutputPreview) { RKGlobals::rInterface ()->issueCommand ("local ({\n" "outfile <- tempfile (fileext='html')\n" "rk.assign.preview.data(" + idprop + ", list (filename=outfile, on.delete=function (id) {\n" " rk.flush.output (outfile, ask=FALSE)\n" " unlink (outfile)\n" "}))\n" "oldfile <- rk.set.output.html.file (outfile, style='preview') # for initialization\n" "rk.set.output.html.file (oldfile)\n" "})\n" + placement_command + "rk.show.html(rk.get.preview.data (" + idprop + ")$filename)" + placement_end, RCommand::Plugin | RCommand::Sync); } else { // For all others, create an empty data.frame as dummy. Even for custom docked previews it has the effect of initializing the preview area with _something_. RKGlobals::rInterface ()->issueCommand ("local ({\nrk.assign.preview.data(" + idprop + ", data.frame ())\n})\n" + placement_command + "rk.edit(rkward::.rk.variables$.rk.preview.data[[" + idprop + "]])" + placement_end, RCommand::Plugin | RCommand::Sync); } // A bit of a hack: For now, in wizards, docked previews are always active, and control boxes are meaningless. if (uicomp->isWizardish ()) { hide (); toggle_preview_box->setChecked (true); } } } // find and connect to code property of the parent QString dummy; RKComponentBase *cp = parentComponent ()->lookupComponent ("code", &dummy); if (cp && dummy.isNull () && (cp->type () == PropertyCode)) { code_property = static_cast<RKComponentPropertyCode *> (cp); connect (code_property, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (changedCode(RKComponentPropertyBase*))); } else {