Hello,

I'd like to send an update of rkward. I've added to the configure packages
interface a new tab ( install new) which is basically the same as the
install tab except that it only shows packages that haven't been installed
yet.
Hope you will use this.

Greetings,

M. D. Vreeburg
Index: rkward/rkward/dialogs/rkloadlibsdialog.cpp
===================================================================
--- rkward/rkward/dialogs/rkloadlibsdialog.cpp	(revision 3723)
+++ rkward/rkward/dialogs/rkloadlibsdialog.cpp	(working copy)
@@ -64,10 +64,15 @@
 	connect (this, SIGNAL (installedPackagesChanged ()), luwidget, SLOT (updateInstalledPackages ()));
 
 	addPage (new UpdatePackagesWidget (this), i18n ("Update"));
-
+	
+	addPage (new InstallNewPackagesWidget (this), i18n ("Install New"));
+	
 	install_packages_widget = new InstallPackagesWidget (this);
 	install_packages_pageitem = addPage (install_packages_widget, i18n ("Install"));
 
+/**	install_new_packages_widget = new InstallNewPackagesWidget (this);
+	install_new_packages_pageitem = addPage (install_new_packages_widget, i18n ("Install New")); */
+	
 	setButtonText (KDialog::User1, i18n ("Configure Repositories"));
 
 	connect (this, SIGNAL (currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT (slotPageChanged()));
@@ -899,4 +904,158 @@
 	libloc_selector->insertItems (0, newlist);
 }
 
+
+/////////////////////// InstallNewPackagesWidget //////////////////////////
+
+#define FIND_NEW_PACKAGES_COMMAND 1
+
+InstallNewPackagesWidget::InstallNewPackagesWidget (RKLoadLibsDialog *dialog) : QWidget (0) {
+	RK_TRACE (DIALOGS);
+	InstallNewPackagesWidget::parent = dialog;
+	
+	QVBoxLayout *mvbox = new QVBoxLayout (this);
+	mvbox->setContentsMargins (0, 0, 0, 0);
+	QLabel *label = new QLabel (i18n ("Many packages are available on CRAN (Comprehensive R Archive Network), and other repositories (click \"Configure Repositories\" to add more sources). Click \"Fetch List\" to find out, which packages are available. This feature requires a working internet connection."), this);
+	label->setWordWrap (true);
+	mvbox->addWidget (label);
+	QHBoxLayout *hbox = new QHBoxLayout ();
+	mvbox->addLayout (hbox);
+	hbox->setContentsMargins (0, 0, 0, 0);
+	
+	installable_view = new QTreeWidget (this);
+	installable_view->setHeaderLabels (QStringList () << i18n ("Name") << i18n ("Version"));
+	installable_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
+	hbox->addWidget (installable_view);
+	setFocusProxy (installable_view);
+
+	QVBoxLayout *buttonvbox = new QVBoxLayout ();
+	hbox->addLayout (buttonvbox);
+	buttonvbox->setContentsMargins (0, 0, 0, 0);
+	get_list_button = new QPushButton (i18n ("Fetch list"), this);
+	connect (get_list_button, SIGNAL (clicked ()), this, SLOT (getListButtonClicked ()));
+	install_selected_button = new QPushButton (i18n ("Install Selected"), this);
+	connect (install_selected_button, SIGNAL (clicked ()), this, SLOT (installSelectedButtonClicked ()));
+	install_params = new PackageInstallParamsWidget (this, true);
+	connect (parent, SIGNAL (libraryLocationsChanged (const QStringList &)), install_params, SLOT (liblocsChanged (const QStringList &)));
+
+	buttonvbox->addWidget (get_list_button);
+	buttonvbox->addStretch (1);
+	buttonvbox->addWidget (install_selected_button);
+	buttonvbox->addStretch (1);
+	buttonvbox->addWidget (install_params);
+	buttonvbox->addStretch (1);
+	
+	install_selected_button->setEnabled (false);
+	installable_view->setEnabled (false);
+
+	new QTreeWidgetItem (installable_view, QStringList ("..."));	// i18n ("[Click \"Fetch list\" to see available packages]")
+
+	connect (dialog, SIGNAL (okClicked ()), this, SLOT (ok ()));
+	connect (dialog, SIGNAL (cancelClicked ()), this, SLOT (cancel ()));
+	connect (this, SIGNAL (destroyed ()), dialog, SLOT (childDeleted ()));
+}
+
+InstallNewPackagesWidget::~InstallNewPackagesWidget () {
+	RK_TRACE (DIALOGS);
+}
+
+void InstallNewPackagesWidget::rCommandDone (RCommand *command) {
+	RK_TRACE (DIALOGS);
+	if (command->getFlags () == FIND_NEW_PACKAGES_COMMAND) {
+		if (!command->failed ()) {
+			installable_view->clear ();
+
+			RK_ASSERT (command->getDataLength () == 3);
+
+			RData *names = command->getStructureVector ()[0];
+			RData *versions = command->getStructureVector ()[1];
+			RData *repos = command->getStructureVector ()[2];
+
+			unsigned int count = names->getDataLength ();
+			RK_ASSERT (count == versions->getDataLength ());
+			RK_ASSERT (repos->getDataLength () == 1);
+
+			for (unsigned int i=0; i < count; ++i) {
+				QTreeWidgetItem* item = new QTreeWidgetItem (installable_view);
+				item->setText (0, names->getStringVector ()[i]);
+				item->setText (1, versions->getStringVector ()[i]);
+			}
+
+			if (installable_view->topLevelItemCount ()) {
+				install_selected_button->setEnabled (true);
+				installable_view->setEnabled (true);
+				installable_view->setFocus ();
+				installable_view->setSortingEnabled (true);
+				installable_view->sortItems (0, Qt::AscendingOrder);
+			} else {
+				new QTreeWidgetItem (installable_view, QStringList (i18n ("[No packages available]")));
+			}
+			installable_view->resizeColumnToContents (0);
+
+			// this is after the repository was chosen. Update the repository string.
+			parent->repos_string = repos->getStringVector ()[0];
+		} else {
+			get_list_button->setEnabled (true);
+		}
+	} else {
+		RK_ASSERT (false);
+	}
+}
+
+void InstallNewPackagesWidget::installPackages (const QStringList &list) {
+	RK_TRACE (DIALOGS);
+	bool as_root = false;
+
+	if (list.isEmpty ()) return;
+	if (!install_params->checkWritable (&as_root)) return;
+
+	parent->installPackages (list, install_params->libraryLocation (), install_params->installDependencies (), as_root);
+}
+
+void InstallNewPackagesWidget::installSelectedButtonClicked () {
+	RK_TRACE (DIALOGS);
+	QStringList list;
+	QList<QTreeWidgetItem*> selected = installable_view->selectedItems ();
+	for (int i = 0; i < selected.count (); ++i) {
+		list.append (selected[i]->text (0));
+	}
+	installPackages (list);
+}
+
+void InstallNewPackagesWidget::getListButtonClicked () {
+	RK_TRACE (DIALOGS);
+
+	get_list_button->setEnabled (false);
+
+	RCommand *command = new RCommand (".rk.get.new.packages ()", RCommand::App | RCommand::GetStructuredData, QString::null, this, FIND_NEW_PACKAGES_COMMAND);
+	RKProgressControl *control = new RKProgressControl (this, i18n ("Please stand by while downloading the list of new packages."), i18n ("Fetching list"), RKProgressControl::CancellableProgress | RKProgressControl::AutoCancelCommands);
+	control->addRCommand (command, true);
+	RKGlobals::rInterface ()->issueCommand (command, parent->chain);
+	control->doModal (true);
+}
+
+void InstallNewPackagesWidget::trySelectPackage (const QString &package_name) {
+	RK_TRACE (DIALOGS);
+
+	QList<QTreeWidgetItem*> found = installable_view->findItems (package_name, Qt::MatchExactly, 0);
+	if (found.isEmpty ()) {
+		KMessageBox::sorry (0, i18n ("The package requested by the backend (\"%1\") was not found in the package repositories. Maybe the package name was mis-spelled. Or maybe you need to add additional repositories via the \"Configure Repositories\"-button.", package_name), i18n ("Package not available"));
+	} else {
+		RK_ASSERT (found.count () == 1);
+		installable_view->setCurrentItem (found[0]);
+		found[0]->setSelected (true);
+		installable_view->scrollToItem (found[0]);
+	}
+}
+
+void InstallNewPackagesWidget::ok () {
+	RK_TRACE (DIALOGS);
+	deleteLater ();
+}
+
+void InstallNewPackagesWidget::cancel () {
+	RK_TRACE (DIALOGS);
+	deleteLater ();
+}
+
 #include "rkloadlibsdialog.moc"
Index: rkward/rkward/dialogs/rkloadlibsdialog.h
===================================================================
--- rkward/rkward/dialogs/rkloadlibsdialog.h	(revision 3723)
+++ rkward/rkward/dialogs/rkloadlibsdialog.h	(working copy)
@@ -84,12 +84,16 @@
 	void tryDestruct ();
 friend class LoadUnloadWidget;
 friend class UpdatePackagesWidget;
+friend class InstallNewPackagesWidget;
 friend class InstallPackagesWidget;
 	RCommandChain *chain;
 
 	InstallPackagesWidget *install_packages_widget;	// needed for automated installation
 	KPageWidgetItem *install_packages_pageitem;
-
+	
+/**	InstallNewPackagesWidget *install_new_packages_widget;	// needed for automated installation
+	KPageWidgetItem *install_new_packages_pageitem; */
+	
 	QString auto_install_package;
 	int num_child_widgets;
 	bool accepted;
@@ -98,6 +102,8 @@
 	QProcess* installation_process;
 };
 
+
+
 /**
 Shows which packages are available (installed) / loaded, and lets the user load or detach packages.
 To be used in RKLoadLibsDialog
@@ -201,6 +207,37 @@
 };
 
 /**
+Allows the user to install further R packages. Shows only non installed packages.
+Ro be used in RKLoadLibsDialog.
+
+@author Thomas Friedrichsmeier
+*/
+class InstallNewPackagesWidget : public QWidget, public RCommandReceiver {
+Q_OBJECT
+public:
+	InstallNewPackagesWidget (RKLoadLibsDialog *dialog);
+	
+	~InstallNewPackagesWidget ();
+	void trySelectPackage (const QString &package_name);
+public slots:
+	void installSelectedButtonClicked ();
+	void getListButtonClicked ();
+	void ok ();
+	void cancel ();
+protected:
+	void rCommandDone (RCommand *command);
+private:
+	void installPackages (const QStringList &list);
+	QTreeWidget *installable_view;
+
+	QPushButton *install_selected_button;
+	QPushButton *get_list_button;
+	PackageInstallParamsWidget *install_params;
+	
+	RKLoadLibsDialog *parent;
+};
+
+/**
 Simple helper class for RKLoadLibsDialog to allow selection of installation parameters
 
 @author Thomas Friedrichsmeier
Index: rkward/rkward/rbackend/rpackages/rkward/R/internal.R
===================================================================
--- rkward/rkward/rbackend/rpackages/rkward/R/internal.R	(revision 3723)
+++ rkward/rkward/rbackend/rpackages/rkward/R/internal.R	(working copy)
@@ -134,6 +134,36 @@
 	return (list (as.character (x[,1]), as.character (x[,2]), rk.make.repos.string ()))
 }
 
+
+".rk.new.packages.cache" <- NULL
+# This function works like available.packages (with no arguments), but does simple caching of the result, and of course uses a cache if available. Cache is only used, if it is less than 1 hour old, and options("repos") is unchanged.
+
+".rk.cached.new.packages" <- function () {
+	x <- NULL
+	if (exists (".rk.new.packages.cache") && (!is.null (.rk.new.packages.cache))) {
+		if (.rk.new.packages.cache$timestamp > (Sys.time () - 30)) {
+			if (all (.rk.new.packages.cache$repos$repos == options ("repos")$repos)) {
+				x <- .rk.new.packages.cache$cache
+			}
+		}
+	}
+	
+	if (is.null(x)) {
+		aval<-available.packages()
+		new<-new.packages(checkBuilt=TRUE)
+		aval.new<-aval[,1] %in% new
+		x<-aval[aval.new,]
+		.rk.new.packages.cache <<- list (cache = x, timestamp = Sys.time (), repos = options ("repos"))
+	}
+
+	return (x)
+}
+
+".rk.get.new.packages" <- function () {
+	x <- .rk.cached.new.packages ()
+	return (list (as.character (x[,1]), as.character (x[,2]), rk.make.repos.string ()))
+}
+
 "require" <- function (package, quietly = FALSE, character.only = FALSE, ...)
 {
 	if (!character.only) {
------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system, 
user administration capabilities and model configuration. Take 
the hassle out of deploying and managing Subversion and the 
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
RKWard-devel mailing list
RKWard-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rkward-devel

Reply via email to