[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