[rkward/frameworks] /: Merge branch 'master' into frameworks

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Wed Dec 30 13:50:04 UTC 2015


Git commit d5eeba62ddda02c2d78ddff8b4e3e497d184566c by Thomas Friedrichsmeier.
Committed on 30/12/2015 at 13:49.
Pushed by tfry into branch 'frameworks'.

Merge branch 'master' into frameworks

M  +6    -1    ChangeLog
M  +5    -5    rkward/main.cpp
M  +5    -1    rkward/misc/rkaccordiontable.cpp
M  +3    -7    rkward/misc/rkdbusapi.cpp
M  +11   -3    rkward/plugin/rkcomponentproperties.cpp
M  +2    -0    rkward/plugin/rkcomponentproperties.h
M  +7    -6    rkward/plugin/rkvarslot.cpp
M  +1    -1    rkward/rbackend/rpackages/CMakeLists.txt
M  +34   -12   rkward/rkward.cpp
M  +1    -0    rkward/rkward.h
M  +5    -2    rkward/rkward_startup_wrapper.cpp
M  +2    -1    rkward/settings/rksettingsmoduler.cpp
M  +2    -1    rkward/windows/rkhtmlwindow.cpp

http://commits.kde.org/rkward/d5eeba62ddda02c2d78ddff8b4e3e497d184566c

diff --cc ChangeLog
index 90bc0f5,6306235..779d187
--- a/ChangeLog
+++ b/ChangeLog
@@@ -1,9 -1,8 +1,14 @@@
 +- File selection fields in plugin dialogs remember the last used directory (per session), and check for a valid selection
 +- Better handling of text drag-and-drop inside the R console window
 +
- --- Version 0.6.4 - XXXXXXXXXXXXXXX
++--- Version 0.6.5 - XXXXXXXXXXXXXXX
 +
 +
+ - Show a warning screen when invoking plugins from the command line (or from clicking an rkward://-link in an external application)
+ 
+ --- Version 0.6.4 - Dec-20-2015
+ - Fixed: Plugin variable slots taking more than one object would not be hightlighted in red while invalid
+ - Plugins check for correct object type, in more places, but allow to proceed with questionable object selections
  - Fixed: RKWard package repository would be listed twice on fresh installations
  - Switch to bugs.kde.org as primary issue tracker
  - Workspace browser gains functionality to search / filter objects by name
diff --cc rkward/main.cpp
index 156df0f,2fcbe07..ad54a3f
--- a/rkward/main.cpp
+++ b/rkward/main.cpp
@@@ -129,72 -162,31 +129,72 @@@ int main (int argc, char *argv[]) 
  	for (int i = 1; i < argc; ++i) {
  		argv_copy[i] = argv[i];
  	}
 -	KCmdLineArgs::init (argc, argv_copy, &aboutData);
 -	KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
  
 -	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
 -	RK_Debug_Level = DL_FATAL - QString (args->getOption ("debug-level")).toInt ();
 -	RK_Debug_Flags = QString (args->getOption ("debug-flags")).toInt ();
 -	if (!args->getOption ("debugger").isEmpty ()) {
 +	QApplication app (argc, argv_copy);
 +	// Don't complain when linking rkward://-pages from Rd pages
 +	KUrlAuthorized::allowUrlAction ("redirect", QUrl("http://"), QUrl ("rkward://"));
 +	// Don't complain when trying to open help pages
 +	KUrlAuthorized::allowUrlAction ("redirect", QUrl("rkward://"), QUrl ("help:"));
 +
 +	KAboutData aboutData ("rkward", i18n ("RKWard"), RKWARD_VERSION, i18n ("Frontend to the R statistics language"), KAboutLicense::GPL, i18n ("(c) 2002, 2004 - 2015"), QString (), "http://rkward.kde.org");
 +	aboutData.addAuthor (i18n ("Thomas Friedrichsmeier"), i18n ("Project leader / main developer"));
 +	aboutData.addAuthor (i18n ("Pierre Ecochard"), i18n ("C++ developer between 2004 and 2007"));
 +	aboutData.addAuthor (i18n ("Prasenjit Kapat"), i18n ("Many plugins, suggestions, plot history feature"));
 +	aboutData.addAuthor (i18n ("Meik Michalke"), i18n ("Many plugins, suggestions, rkwarddev package"));
 +	aboutData.addAuthor (i18n ("Stefan Roediger"), i18n ("Many plugins, suggestions, marketing, translations"));
 +	aboutData.addCredit (i18n ("Contributors in alphabetical order"));
++	aboutData.addCredit (i18n ("Björn Balazs"), i18n ("Extensive usability feedback"));
++	aboutData.addCredit (i18n ("Aaron Batty"), i18n ("Whealth of feedback, hardware donations"));
++	aboutData.addCredit (i18n ("Jan Dittrich"), i18n ("Extensive usability feedback"));
 +	aboutData.addCredit (i18n ("Philippe Grosjean"), i18n ("Several helpful comments and discussions"));
 +	aboutData.addCredit (i18n ("Adrien d'Hardemare"), i18n ("Plugins and patches"));
 +	aboutData.addCredit (i18n ("Yves Jacolin"), i18n ("New website"));
 +	aboutData.addCredit (i18n ("Germán Márquez Mejía"), i18n ("HP filter plugin, spanish translation"), 0);
 +	aboutData.addCredit (i18n ("Marco Martin"), i18n ("A cool icon"));
 +	aboutData.addCredit (i18n ("Daniele Medri"), i18n ("RKWard logo, many suggestions, help on wording"));
 +	aboutData.addCredit (i18n ("David Sibai"), i18n ("Several valuable comments, hints and patches"));
 +	aboutData.addCredit (i18n ("Ilias Soumpasis"), i18n ("Translation, Suggestions, plugins"));
 +	aboutData.addCredit (i18n ("Ralf Tautenhahn"), i18n ("Many comments, useful suggestions, and bug reports"));
 +	aboutData.addCredit (i18n ("Jannis Vajen"), i18n ("German Translation, bug reports"));
 +	aboutData.addCredit (i18n ("Roland Vollgraf"), i18n ("Some patches"));
 +	aboutData.addCredit (i18n ("Roy Qu"), i18n ("patches and helpful comments"));
 +	aboutData.addCredit (i18n ("Many more people on rkward-devel at kde.org"), i18n ("Sorry, if we forgot to list you. Please contact us to get added"));
 +	KAboutData::setApplicationData (aboutData);
 +
 +	QCommandLineParser parser;
 +	parser.addVersionOption ();
 +	parser.addHelpOption ();
 +	parser.addOption (QCommandLineOption ("evaluate", i18n ("After starting (and after loading the specified workspace, if applicable), evaluate the given R code."), "Rcode", QString ()));
 +	parser.addOption (QCommandLineOption ("debug-level", i18n ("Verbosity of debug messages (0-5)"), "level", "2"));
 +	parser.addOption (QCommandLineOption ("debug-flags", i18n ("Mask for components to debug (see debug.h)"), "flags", QString::number (DEBUG_ALL)));
 +	parser.addOption (QCommandLineOption ("debugger", i18n ("Debugger for the frontend. Specify last, or add '--' after all debugger arguments"), "command and arguments", QString ()));
 +	parser.addOption (QCommandLineOption ("backend-debugger", i18n ("Debugger for the backend. (Enclose any debugger arguments in single quotes ('') together with the command. Make sure to re-direct stdout!)"), "command", QString ()));
 +	parser.addOption (QCommandLineOption ("r-executable", i18n ("Use specified R installation, instead of the one configured at compile time (note: rkward R library must be installed to that installation of R)"), "command", QString ()));
 +	parser.addOption (QCommandLineOption ("reuse", i18n ("Reuse a running RKWard instance (if available). If a running instance is reused, only the file arguments will be interpreted, all other options will be ignored.")));
 +	parser.addPositionalArgument ("files", i18n ("File or files to open, typically a workspace, or an R script file. When loading several things, you should specify the workspace, first."), "[Files...]");
 +
 +	aboutData.setupCommandLine (&parser);
 +	parser.process (app);
 +	aboutData.processCommandLine (&parser);
 +
 +	RK_Debug_Level = DL_FATAL - QString (parser.value ("debug-level")).toInt ();
 +	RK_Debug_Flags = QString (parser.value ("debug-flags")).toInt ();
 +	if (!parser.value ("debugger").isEmpty ()) {
  		RK_DEBUG (DEBUG_ALL, DL_ERROR, "--debugger option should have been handled by wrapper script. Ignoring.");
  	}
  
 -	if (args->count ()) {
 -		QStringList urls_to_open;
 -		for (int i = 0; i < args->count (); ++i) {
 -			urls_to_open.append (KCmdLineArgs::makeURL (decodeArgument (args->arg (i)).toUtf8 ()).url ());
 -		}
 -		RKGlobals::startup_options["initial_urls"] = urls_to_open;
 +	QStringList url_args = parser.positionalArguments ();
 +	if (!url_args.isEmpty ()) {
- 		QVariantList urls_to_open;
- 		for (int i = 0; i < url_args.count (); ++i) {
- 			urls_to_open.append (QUrl::fromUserInput (url_args[i], QDir::currentPath(), QUrl::AssumeLocalFile));
- 		}
- 		RKGlobals::startup_options["initial_urls"] = urls_to_open;
++		RKGlobals::startup_options["initial_urls"] = urls_args;
+ 		RKGlobals::startup_options["warn_external"] = args->isSet ("warn-external");
  	}
 -	RKGlobals::startup_options["evaluate"] = decodeArgument (args->getOption ("evaluate"));
 -	RKGlobals::startup_options["backend-debugger"] = decodeArgument (args->getOption ("backend-debugger"));
 +	RKGlobals::startup_options["evaluate"] = decodeArgument (parser.value ("evaluate"));
 +	RKGlobals::startup_options["backend-debugger"] = decodeArgument (parser.value ("backend-debugger"));
  
 -	RKWardApplication app;
  	// No, I do not really understand the point of separating KDE_LANG from LANGUAGE. We do honor it in so far as not
  	// forcing LANGUAGE on the backend, though. Having language as LANGUAGE makes code in RKMessageCatalog much easier compared to KCatalog.
 -	qputenv ("LANGUAGE", QFile::encodeName (KGlobal::locale ()->language ()));
 +	// KF5 TODO: is this still needed at all? Does KDE_LANG still exist?
 +	qputenv ("LANGUAGE", QLocale ().bcp47Name ().section ('-', 0, 0).toAscii ());
  	// install message handler *after* the componentData has been initialized
  	RKSettingsModuleDebug::debug_file = new QTemporaryFile (QDir::tempPath () + "/rkward.frontend");
  	RKSettingsModuleDebug::debug_file->setAutoRemove (false);
diff --cc rkward/misc/rkaccordiontable.cpp
index bc3e5f5,f44c2b0..0bb1807
--- a/rkward/misc/rkaccordiontable.cpp
+++ b/rkward/misc/rkaccordiontable.cpp
@@@ -148,12 -148,13 +148,13 @@@ public
  		return createIndex (child.internalId (), 0, real_item_id);
  	}
  
 -	void setSourceModel (QAbstractItemModel* source_model) {
 +	void setSourceModel (QAbstractItemModel* source_model) override {
  		/* More than these would be needed for a proper proxy of any model, but in our case, we only have to support the RKOptionsetDisplayModel */
 -		connect (source_model, SIGNAL (rowsInserted(const QModelIndex&,int,int)), this, SLOT (r_rowsInserted(QModelIndex,int,int)));
 -		connect (source_model, SIGNAL (rowsRemoved(const QModelIndex&,int,int)), this, SLOT (r_rowsRemoved(QModelIndex,int,int)));
 -		connect (source_model, SIGNAL (dataChanged(QModelIndex,QModelIndex)), this, SLOT (r_dataChanged(QModelIndex,QModelIndex)));
 -		connect (source_model, SIGNAL (headerDataChanged(Qt::Orientation,int,int)), this, SLOT (r_headerDataChanged(Qt::Orientation,int,int)));
 -		connect (source_model, SIGNAL (layoutChanged()), this, SLOT (r_layoutChanged()));
 +		connect (source_model, &QAbstractItemModel::rowsInserted, this, &RKAccordionDummyModel::r_rowsInserted);
 +		connect (source_model, &QAbstractItemModel::rowsRemoved, this, &RKAccordionDummyModel::r_rowsRemoved);
 +		connect (source_model, &QAbstractItemModel::dataChanged, this, &RKAccordionDummyModel::r_dataChanged);
++		connect (source_model, &QAbstractItemModel::headerDataChanged, this, &RKAccordionDummyModel::r_headerDataChanged);
 +		connect (source_model, &QAbstractItemModel::layoutChanged, this, &RKAccordionDummyModel::r_layoutChanged);
  		QAbstractProxyModel::setSourceModel (source_model);
  	}
  
diff --cc rkward/misc/rkdbusapi.cpp
index acfd6e5,3ec6fa4..c862fee
--- a/rkward/misc/rkdbusapi.cpp
+++ b/rkward/misc/rkdbusapi.cpp
@@@ -55,10 -55,7 +55,6 @@@ void RKDBusAPI::openAnyUrl (const QStri
  #endif
  	// end
  
- 	RKWardMainWindow::getMain ()->setMergeLoads (true);
- 	for (int i = 0; i < urls.size (); ++i) {
- 		RKWorkplace::mainWorkplace ()->openAnyUrl (QUrl::fromUserInput (urls[i], QString (), QUrl::AssumeLocalFile));
- 	}
- 	RKWardMainWindow::getMain ()->setMergeLoads (false);
+ 	RKWardMainWindow::getMain ()->openUrlsFromCommandLineOrDBus (warn_external, urls);
  }
  
 -#include "rkdbusapi.moc"
diff --cc rkward/plugin/rkcomponentproperties.h
index da99936,2a9706a..9fda1e5
--- a/rkward/plugin/rkcomponentproperties.h
+++ b/rkward/plugin/rkcomponentproperties.h
@@@ -316,29 -316,30 +316,30 @@@ public
  @returns an empty list if no valid object is selected */
  	RObject::ObjectList objectList ();
  /** reimplemented from RKComponentPropertyBase. Modifier "label" returns label(s). Modifier "shortname" returns short name(s). Modifier QString () returns full name. If no object is set, returns an empty string / variant */
 -	QVariant value (const QString &modifier=QString ());
 +	QVariant value (const QString &modifier=QString ()) override;
  /** reimplemented from RKComponentPropertyBase to convert to RObject with current constraints
  @returns false if no such object(s) could be found or the object(s) are invalid */
 -	bool setValue (const QString &value);
 +	bool setValue (const QString &value) override;
  /** overload of setValue() which accepts a list of names of RObjects
  @returns false if no such object(s) could be found or the object(s) are invalid */
 -	bool setValueList (const QStringList &values);
 +	bool setValueList (const QStringList &values) override;
  /** reimplemented from RKComponentPropertyBase to test whether conversion to RObject is possible with current constraints */
 -	bool isStringValid (const QString &value);
 +	bool isStringValid (const QString &value) override;
  /** RTTI */
 -	int type () { return PropertyRObjects; };
 +	int type () override { return PropertyRObjects; };
  /** reimplemented from RKComponentPropertyBase to actually reconcile requirements with other object properties */
 -	void connectToGovernor (RKComponentPropertyBase *governor, const QString &modifier=QString (), bool reconcile_requirements=true);
 +	void connectToGovernor (RKComponentPropertyBase *governor, const QString &modifier=QString (), bool reconcile_requirements=true) override;
  /** reimplemented from RKComponentPropertyBase to use special handling for object properties */
 -	void governorValueChanged (RKComponentPropertyBase *property);
 -	void removeAt (int index);
 +	void governorValueChanged (RKComponentPropertyBase *property) override;
 +	void removeAt (int index) override;
  	RObject* objectAt (int index) const { return object_list.value (index); };
 -	int listLength () const { return (object_list.size ()); };
 +	int listLength () const override { return (object_list.size ()); };
+ 	void setObjectProblemsAreErrors (bool errors);
  protected:
  /** remove an object value. reimplemented from RObjectListener::objectRemoved (). This is so we get notified if the object currently selected is removed TODO: is this effectively a duplication of setFromList? */
 -	void objectRemoved (RObject *removed);
 +	void objectRemoved (RObject *removed) override;
  /** reimplemented from RObjectListener::objectMetaChanged (). This is so we get notified if the object currently selected is changed */
 -	void objectMetaChanged (RObject *changed);
 +	void objectMetaChanged (RObject *changed) override;
  private:
  /** check all objects currently in the list for validity. And set validity state accordingly. */
  	void validizeAll (bool silent=false);
diff --cc rkward/rkward.cpp
index 9fef045,ee13bf0..30283e5
--- a/rkward/rkward.cpp
+++ b/rkward/rkward.cpp
@@@ -220,22 -217,21 +221,20 @@@ void RKWardMainWindow::doPostInit () 
  		}
  	}
  #endif
+ 	KMessageBox::enableMessage ("external_link_warning");
  
 -	KUrl recover_url = RKRecoverDialog::checkRecoverCrashedWorkspace ();
 +	QUrl recover_url = RKRecoverDialog::checkRecoverCrashedWorkspace ();
  	if (!recover_url.isEmpty ()) {
- 		open_urls.clear ();
- 		open_urls.append (recover_url);		// Well, not a perfect solution. But we certainly don't want to overwrite the just recovered workspace.
+ 		open_urls.clear ();    // Well, not a perfect solution. But we certainly don't want to overwrite the just recovered workspace.
+ 		open_urls.append (recover_url.url ());
  	}
  
- 	setMergeLoads (true);
  	for (int i = 0; i < open_urls.size (); ++i) {
  		// make sure local urls are absolute, as we may be changing wd before loading
- 		QUrl url = open_urls[i].toUrl ();
- 		if (url.isRelative ()) {
- 			open_urls[i] = QUrl::fromLocalFile (QDir::current ().absoluteFilePath (url.toLocalFile ()));
- 		}
 -		KUrl url = open_urls[i];
 -		if (url.isRelative ()) {
 -			open_urls[i] = QDir::current ().absoluteFilePath (url.toLocalFile ());
 -		}
++		QUrl url (open_urls[i]), QDir::currentPath(), QUrl::AssumeLocalFile));
++		RK_ASSERT (!url.isRelative ());
++		open_urls[i] = url.url ();
  	}
- 	setMergeLoads (false);
  
  	QString cd_to = RKSettingsModuleGeneral::initialWorkingDirectory ();
  	if (!cd_to.isEmpty ()) {
@@@ -282,6 -276,31 +279,31 @@@
  	setCaption (QString ());	// our version of setCaption takes care of creating a correct caption, so we do not need to provide it here
  }
  
+ void RKWardMainWindow::openUrlsFromCommandLineOrDBus (bool warn_external, QStringList urls) {
+ 	RK_TRACE (APP);
+ 
+ 	bool any_dangerous_urls = false;
+ 	for (int i = 0; i < urls.size (); ++i) {
 -		QUrl url = urls[i];
++		QUrl url = QUrl::fromUserInput (urls[i], QString (), QUrl::AssumeLocalFile);
+ 		if (url.scheme () == "rkward" && url.host () == "runplugin") {
+ 			any_dangerous_urls = true;
+ 			break;
+ 		}
+ 	}
+ 
+ 	if (warn_external && any_dangerous_urls) {
+ 		RK_ASSERT (urls.size () == 1);
+ 		QString message = i18n ("<p>You are about to start an RKWard dialog from outside of RKWard, probably by clicking on an 'rkward://'-link, somewhere. In case you have found this link on an external website, please bear in mind that R can be used to run arbitrary commands on your computer, <b>potentially including downloading and installing malicious software</b>. If you do not trust the source of the link you were following, you should press 'Cancel', below.</p><p>In case you click 'Continue', no R code will be run, unless and until you click 'Submit' in the dialog window, and you are encouraged to review the generated R code, before doing so.</p><p><i>Note</i>: Checking 'Do not ask again' will suppress this message for the remainder of this session, only.");
+ 		if (KMessageBox::warningContinueCancel (this, message, i18n ("A note on external links"), KStandardGuiItem::cont (), KStandardGuiItem::cancel (), "external_link_warning") != KMessageBox::Continue) return;
+ 	}
+ 
+ 	RKWardMainWindow::getMain ()->setMergeLoads (true);
+ 	for (int i = 0; i < urls.size (); ++i) {
+ 		RKWorkplace::mainWorkplace ()->openAnyUrl (urls[i], QString (), false);
+ 	}
+ 	RKWardMainWindow::getMain ()->setMergeLoads (false);
+ }
+ 
  void RKWardMainWindow::initPlugins (const QStringList &automatically_added) {
  	RK_TRACE (APP);
  	slotSetStatusBarText(i18n("Setting up plugins..."));
diff --cc rkward/rkward.h
index c116cab,22c7124..80edeff
--- a/rkward/rkward.h
+++ b/rkward/rkward.h
@@@ -130,9 -130,11 +130,10 @@@ public slots
  	void slotDetachWindow ();
  
  /** reimplemented from KMainWindow, to additionally include the workspace url. Parameters are ignored. Rather we create a caption according to the active view */
 -	void setCaption (const QString &);
 +	void setCaption (const QString &) override;
  /** HACK this is only to make the compiler happy with -Woverloaded-virtual */
 -	void setCaption (const QString &dummy, bool) { setCaption (dummy); };
 -
 +	void setCaption (const QString &dummy, bool) override { setCaption (dummy); };
+ 	void openUrlsFromCommandLineOrDBus (bool warn_external, QStringList urls);
  private slots:
  	void partChanged (KParts::Part *new_part);
  private:
diff --cc rkward/settings/rksettingsmoduler.cpp
index 894b5f8,e4ecdca..f09776f
--- a/rkward/settings/rksettingsmoduler.cpp
+++ b/rkward/settings/rksettingsmoduler.cpp
@@@ -344,8 -327,9 +344,9 @@@ void RKSettingsModuleR::loadSettings (K
  	options_editor = cg.readEntry ("editor", builtin_editor);
  	options_pager = cg.readEntry ("pager", builtin_editor);
  	options_further = cg.readEntry ("further init commands", QString ());
 -#ifdef Q_WS_WIN
 +#ifdef Q_OS_WIN
- 	options_internet2 = cg.readEntry ("internet2", false);
+ 	options_internet2 = cg.readEntry ("internet2", true);
+ 	if (RKSettingsModuleGeneral::storedConfigVersion () < RKSettingsModuleGeneral::RKWardConfig_0_6_4) options_internet2 = true;
  #endif
  }
  



More information about the rkward-tracker mailing list