[rkward-cvs] SF.net SVN: rkward:[2765] branches/release_branch_0.4.9
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Sat Mar 6 12:30:49 UTC 2010
Revision: 2765
http://rkward.svn.sourceforge.net/rkward/?rev=2765&view=rev
Author: tfry
Date: 2010-03-06 12:30:49 +0000 (Sat, 06 Mar 2010)
Log Message:
-----------
Backport support for dynamic help server.
(Merge commits 2672, 2677, 2701, and some further snippets from trunk)
Modified Paths:
--------------
branches/release_branch_0.4.9/ChangeLog
branches/release_branch_0.4.9/rkward/rbackend/rpackages/rkward/R/internal.R
branches/release_branch_0.4.9/rkward/rbackend/rthread.cpp
branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.cpp
branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.h
branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.cpp
branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.h
branches/release_branch_0.4.9/rkward/windows/rkhtmlwindow.cpp
Modified: branches/release_branch_0.4.9/ChangeLog
===================================================================
--- branches/release_branch_0.4.9/ChangeLog 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/ChangeLog 2010-03-06 12:30:49 UTC (rev 2765)
@@ -1,3 +1,6 @@
+- Add support for the dynamic help server introduced in R 2.10.0
+- Backport some improvements in event handling
+- Fix deadlock while handling some Tcl events
- Fix: Warn before saving file that was modified on disk, externally
- Fix: Do not try to open mimetypes other than text/html directly in the help browser.
- Fixed: Screen device in rkward was not seen as interactive by R
Modified: branches/release_branch_0.4.9/rkward/rbackend/rpackages/rkward/R/internal.R
===================================================================
--- branches/release_branch_0.4.9/rkward/rbackend/rpackages/rkward/R/internal.R 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/rbackend/rpackages/rkward/R/internal.R 2010-03-06 12:30:49 UTC (rev 2765)
@@ -481,3 +481,38 @@
".rk.cat.output" <- function (x) {
cat (x, file = rk.get.output.html.file(), append = TRUE)
}
+
+# retrieve the (expected) "base" url of help files. Most importantly this will be a local port for R 2.10.0 and above, but a local directory for 2.9.x and below. As a side effect, in R 2.10.0 and above, the dynamic help server is started.
+".rk.getHelpBaseUrl" <- function () {
+ port <- NA
+ if (compareVersion (as.character (getRversion()), "2.10.0") >= 0) {
+ try ({
+ port <- tools::startDynamicHelp ()
+ })
+ if (is.na (port)) {
+ try ({
+ port <- tools:::httpdPort
+ })
+ }
+ }
+ if (is.na (port)) {
+ return (paste ("file://", R.home (), sep=""))
+ }
+ return (paste ("http://127.0.0.1", port, sep=":"))
+}
+
+# a simple wrapper around help() that makes it easier to detect in code, whether help was found or not.
+# used from RKHelpSearchWindow::getFunctionHelp
+".rk.getHelp" <- function (...) {
+ if (compareVersion (as.character (getRversion()), "2.10.0") >= 0) {
+ res <- help (..., help_type="html")
+ } else {
+ res <- help (..., chmhelp=FALSE, htmlhelp=TRUE)
+ }
+ if (!length (as.character (res))) { # this seems undocumented, but it is what utils:::print.help_files_with_topic checks
+ show (res)
+ stop ("No help found")
+ }
+ show (res)
+ invisible (TRUE)
+}
Modified: branches/release_branch_0.4.9/rkward/rbackend/rthread.cpp
===================================================================
--- branches/release_branch_0.4.9/rkward/rbackend/rthread.cpp 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/rbackend/rthread.cpp 2010-03-06 12:30:49 UTC (rev 2765)
@@ -486,6 +486,15 @@
}
delete [] standardliblocs;
+// start help server / determined help base url
+ QString *help_base_url = getCommandAsStringVector (".rk.getHelpBaseUrl ()\n", &c, &error);
+ if (error) status |= OtherFail;
+ else {
+ RK_ASSERT (c == 1);
+ RKSettingsModuleR::help_base_url = help_base_url[0];
+ }
+ delete [] help_base_url;
+
// apply user configurable run time options
QStringList commands = RKSettingsModuleR::makeRRunTimeOptionCommands () + RKSettingsModuleRPackages::makeRRunTimeOptionCommands ();
for (QStringList::const_iterator it = commands.begin (); it != commands.end (); ++it) {
@@ -501,7 +510,7 @@
if (error) status |= SinkFail;
runCommandInternal ("rk.set.output.html.file (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\")\n", &error);
if (error) status |= SinkFail;
- runCommandInternal ("options (htmlhelp=TRUE); options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")", &error);
+ runCommandInternal ("options (browser=\"dcop " + kapp->dcopClient ()->appId () + " rkwardapp openHTMLHelp \")\n", &error);
if (error) status |= OtherFail;
// TODO: error-handling?
Modified: branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.cpp
===================================================================
--- branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.cpp 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.cpp 2010-03-06 12:30:49 UTC (rev 2765)
@@ -2,7 +2,7 @@
rksettingsmoduler - description
-------------------
begin : Wed Jul 28 2004
- copyright : (C) 2004, 2007, 2009 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2007, 2009, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -47,6 +47,8 @@
int RKSettingsModuleR::options_digits;
bool RKSettingsModuleR::options_checkbounds;
QString RKSettingsModuleR::options_printcmd;
+// session constants
+QString RKSettingsModuleR::help_base_url;
RKSettingsModuleR::RKSettingsModuleR (RKSettings *gui, QWidget *parent) : RKSettingsModule(gui, parent) {
RK_TRACE (SETTINGS);
@@ -220,6 +222,8 @@
list.append ("options (device=\"rk.screen.device\")\n");
// register as interactive
list.append ("try (deviceIsInteractive(name=\"rk.screen.device\"))\n");
+ list.append ("options (help_type=\"html\")\n"); // for R 2.10.0 and above
+ list.append ("try ({options (htmlhelp=TRUE); options (chmhelp=FALSE)})\n"); // COMPAT: for R 2.9.x and below
return list;
}
Modified: branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.h
===================================================================
--- branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.h 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/settings/rksettingsmoduler.h 2010-03-06 12:30:49 UTC (rev 2765)
@@ -2,7 +2,7 @@
rksettingsmoduler - description
-------------------
begin : Wed Jul 28 2004
- copyright : (C) 2004, 2007 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2007, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -51,6 +51,9 @@
/** generate the commands needed to set the R run time options */
static QStringList makeRRunTimeOptionCommands ();
+
+/** retrieve the (probable) base url of help pages. May change across R sessions */
+ static QString helpBaseUrl () { return help_base_url; };
public slots:
void boxChanged (int);
void pathChanged ();
@@ -79,6 +82,10 @@
static int options_digits;
static bool options_checkbounds;
static QString options_printcmd;
+
+// session constants
+ friend class RThread;
+ static QString help_base_url;
};
/**
Modified: branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.cpp
===================================================================
--- branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.cpp 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.cpp 2010-03-06 12:30:49 UTC (rev 2765)
@@ -2,7 +2,7 @@
rkhelpsearchwindow - description
-------------------
begin : Fri Feb 25 2005
- copyright : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2007, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -36,7 +36,7 @@
#include "../misc/rkcommonfunctions.h"
#include "../misc/rkdummypart.h"
-#define GET_HELP_URL 1
+#define GET_HELP 1
#define HELP_SEARCH 2
#define GET_INSTALLED_PACKAGES 3
@@ -127,9 +127,15 @@
getFunctionHelp (result);
}
-void RKHelpSearchWindow::getFunctionHelp (const QString &function_name) {
+void RKHelpSearchWindow::getFunctionHelp (const QString &function_name, const QString &package) {
RK_TRACE (APP);
- RKGlobals::rInterface ()->issueCommand ("help(\"" + function_name + "\", htmlhelp=TRUE)[1]", RCommand::App | RCommand::GetStringVector, QString::null, this, GET_HELP_URL, 0);
+
+// we use .rk.getHelp() instead of plain help() to receive an error, if no help could be found
+ QString command = ".rk.getHelp(\"" + function_name + '\"';
+ if (!package.isEmpty ()) command.append (", package=" + package);
+ command.append (')');
+
+ RKGlobals::rInterface ()->issueCommand (command, RCommand::App | RCommand::GetStringVector, QString::null, this, GET_HELP, 0);
}
void RKHelpSearchWindow::slotFindButtonClicked () {
@@ -182,13 +188,7 @@
return;
}
- QString s="help(\"";
- s.append (item->text (0));
- s.append ("\", htmlhelp=TRUE, package= \"");
- s.append (item->text (2));
- s.append ("\")");
-
- RKGlobals::rInterface ()->issueCommand (s, RCommand::App | RCommand::Sync | RCommand::GetStringVector, QString::null, this, GET_HELP_URL, 0);
+ getFunctionHelp (item->text (0), item->text (2));
}
void RKHelpSearchWindow::rCommandDone (RCommand *command) {
@@ -202,14 +202,9 @@
new QListViewItem (resultsList, command->getStringVector ()[i], command->getStringVector ()[count + i], command->getStringVector ()[2*count + i]);
}
setEnabled(true);
- } else if (command->getFlags () == GET_HELP_URL) {
- RK_ASSERT (command->getDataLength ());
- url.setPath(command->getStringVector ()[0]);
- if (QFile::exists (url.path ())) {
- RKWardMainWindow::getMain ()->openHTML (url);
- return;
- } else {
- KMessageBox::sorry (this, i18n ("No help found on '%1'. Maybe the corresponding package is not installed/loaded, or maybe you mistyped the command. Try using Help->Search R Help for more options.").arg (command->command ().section ("\"", 1, 1)), i18n ("No help found"));
+ } else if (command->getFlags () == GET_HELP) {
+ if (command->failed ()) {
+ KMessageBox::sorry (this, i18n ("No help found on '%1'. Maybe the corresponding package is not installed/loaded, or maybe you mistyped the command. Try using Help->Search R Help for more options.").arg (command->command ().section ("\"", 1, 1)), i18n ("No help found"));
}
} else if (command->getFlags () == GET_INSTALLED_PACKAGES) {
RK_ASSERT (command->getDataType () == RData::StringVector);
Modified: branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.h
===================================================================
--- branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.h 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/windows/rkhelpsearchwindow.h 2010-03-06 12:30:49 UTC (rev 2765)
@@ -2,7 +2,7 @@
rkhelpsearchwindow - description
-------------------
begin : Fri Feb 25 2005
- copyright : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2007, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -45,7 +45,7 @@
@param cursor_pos cursor position in the current line
Will figure out the word under the cursor, and provide help on that (if there is such a word, and such help exists) */
void getContextHelp (const QString &context_line, int cursor_pos);
- void getFunctionHelp (const QString &function_name);
+ void getFunctionHelp (const QString &function_name, const QString &package=QString::null);
static RKHelpSearchWindow *mainHelpSearch () { return main_help_search; };
public slots:
void slotFindButtonClicked();
Modified: branches/release_branch_0.4.9/rkward/windows/rkhtmlwindow.cpp
===================================================================
--- branches/release_branch_0.4.9/rkward/windows/rkhtmlwindow.cpp 2010-03-06 11:44:48 UTC (rev 2764)
+++ branches/release_branch_0.4.9/rkward/windows/rkhtmlwindow.cpp 2010-03-06 12:30:49 UTC (rev 2765)
@@ -2,7 +2,7 @@
rkhtmlwindow - description
-------------------
begin : Wed Oct 12 2005
- copyright : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+ copyright : (C) 2005, 2006, 2007, 2010 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -37,6 +37,7 @@
#include "../rkward.h"
#include "../rkconsole.h"
#include "../settings/rksettingsmodulegeneral.h"
+#include "../settings/rksettingsmoduler.h"
#include "../misc/rkcommonfunctions.h"
#include "../misc/xmlhelper.h"
#include "../plugin/rkcomponentmap.h"
@@ -77,7 +78,8 @@
QString RKHTMLWindow::getDescription () {
RK_TRACE (APP);
- return ("help:" + khtmlpart->url ().url ());
+ QString fixed_url = url ().url ().replace (RKSettingsModuleR::helpBaseUrl(), "rkward://RHELPBASE");
+ return ("help:" + fixed_url);
}
bool RKHTMLWindow::isModified () {
@@ -164,6 +166,19 @@
bool RKHTMLWindow::openURL (const KURL &url) {
RK_TRACE (APP);
+ if (!(url.isLocalFile ())) {
+qDebug ("%s", url.url ().local8Bit ().data ());
+ // since R 2.10.0, help urls may be on local ports
+ if (url.protocol ().lower ().startsWith ("http")) {
+ QString host = url.host ().lower ();
+ if ((host == "127.0.0.1") || (host == "localhost")) {
+ khtmlpart->openURL (url);
+ changeURL (url);
+ return true;
+ }
+ }
+ }
+
// asyncrhonously dealing with non-local files would be quite a task. We chose the simple answer instead...
if (!(url.isLocalFile () && KMimeType::findByURL (url)->is ("text/html"))) {
if (KMessageBox::questionYesNo (this, i18n ("The url you are trying to open ('%1') is not a local file or not HTML. Do you want to open the url in the default application?").arg (url.prettyURL ()), i18n ("Open in default application?")) != KMessageBox::Yes) {
@@ -208,6 +223,7 @@
void RKHTMLWindow::updateCaption (const KURL &url) {
RK_TRACE (APP);
+
setCaption (url.filename ());
}
@@ -423,7 +439,10 @@
return true;
} else if (url.host () == "page") {
ok = renderRKHelp (url);
- }
+ } else if (url.host ().upper () == "RHELPBASE") { // NOTE: QUrl () may lowercase the host part, internally
+ QString fixed_url = url.url ().replace (QRegExp (".*RHELPBASE", false), RKSettingsModuleR::helpBaseUrl ());
+ ok = openURL (KURL (fixed_url));
+ }
if (!ok) {
khtmlpart->begin (url);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the rkward-tracker
mailing list