1 /*************************************************************************** 2 rkloadlibsdialog - description 3 ------------------- 4 begin : Mon Sep 6 2004 5 copyright : (C) 2004 - 2015 by Thomas Friedrichsmeier 6 email : thomas.friedrichsmeier@kdemail.net 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 #ifndef RKLOADLIBSDIALOG_H 18 #define RKLOADLIBSDIALOG_H 19 20 #include <kpagedialog.h> 21 22 #include <qstringlist.h> 23 #include <QProcess> 24 #include <QSortFilterProxyModel> 25 26 #include "../settings/rksettingsmoduler.h" 27 #include "../rbackend/rcommandreceiver.h" 28 29 class QLineEdit; 30 class QTreeView; 31 class QTreeWidget; 32 class QSortFilterProxyModel; 33 class QComboBox; 34 class QPushButton; 35 class RKProgressControl; 36 class QWidget; 37 class QCloseEvent; 38 class RCommandChain; 39 class QCheckBox; 40 class PackageInstallParamsWidget; 41 class InstallPackagesWidget; 42 class RKDynamicSearchLine; 43 44 /** 45 Dialog which excapsulates widgets to load/unload, update and install R packages 46 47 @author Thomas Friedrichsmeier 48 */ 49 50 // TODO: add a static member to create (single) instance of the dialog 51 52 class RKLoadLibsDialog : public KPageDialog, public RCommandReceiver { 53 Q_OBJECT 54 public: 55 RKLoadLibsDialog (QWidget *parent, RCommandChain *chain, bool modal=false); 56 57 ~RKLoadLibsDialog (); 58 59 bool installPackages (const QStringList &packages, QString to_libloc, bool install_suggested_packages, const QStringList& repos); 60 bool removePackages (QStringList packages, QStringList from_liblocs); 61 62 /** opens a modal RKLoadLibsDialog with the "Install new Packages" tab on front (To be used when a require () fails in the R backend 63 @param parent parent QWidget. The dialog will be centered there 64 @param chain RCommandChain to run the necessary commands in 65 @param package_name name of the required package */ 66 static void showInstallPackagesModal (QWidget *parent, RCommandChain *chain, const QString &package_name); 67 static void showPluginmapConfig (QWidget *parent=0, RCommandChain *chain=0); currentLibraryLocations()68 QStringList currentLibraryLocations () const { return library_locations; }; 69 void accept () override; 70 void reject () override; 71 signals: 72 void downloadComplete (); 73 void installationComplete (); 74 void libraryLocationsChanged (const QStringList &liblocs); 75 void installationOutput (const QString &output); 76 void installationError (const QString &error); 77 void installedPackagesChanged (); 78 protected: 79 void rCommandDone (RCommand *command) override; 80 void closeEvent (QCloseEvent *e) override; 81 protected slots: 82 void childDeleted (); 83 void processExited (int exitCode, QProcess::ExitStatus exitStatus); 84 void installationProcessOutput (); 85 void installationProcessError (); 86 void automatedInstall (); 87 void slotPageChanged (); 88 private: 89 void addLibraryLocation (const QString &new_loc); 90 void tryDestruct (); 91 void runInstallationCommand (const QString& command, bool as_root, const QString& message, const QString& title); 92 KPageWidgetItem* addChild (QWidget *child_page, const QString &caption); 93 friend class LoadUnloadWidget; 94 friend class InstallPackagesWidget; 95 RCommandChain *chain; 96 97 InstallPackagesWidget *install_packages_widget; // needed for automated installation 98 KPageWidgetItem *install_packages_pageitem; 99 KPageWidgetItem *configure_pluginmaps_pageitem; 100 101 QStringList library_locations; 102 103 QString auto_install_package; 104 int num_child_widgets; 105 bool was_accepted; 106 107 QProcess* installation_process; 108 }; 109 110 /** 111 Shows which packages are available (installed) / loaded, and lets the user load or detach packages. 112 To be used in RKLoadLibsDialog 113 114 @author Thomas Friedrichsmeier 115 */ 116 class LoadUnloadWidget : public QWidget, public RCommandReceiver { 117 Q_OBJECT 118 public: 119 explicit LoadUnloadWidget (RKLoadLibsDialog *dialog); 120 121 ~LoadUnloadWidget (); 122 signals: 123 void loadUnloadDone (); 124 public slots: 125 void loadButtonClicked (); 126 void detachButtonClicked (); 127 void ok (); 128 void apply (); 129 void cancel (); 130 void updateInstalledPackages (); 131 void updateButtons (); 132 void activated (); 133 protected: 134 void rCommandDone (RCommand *command) override; 135 private: 136 void updateCurrentList (); 137 void doLoadUnload (); 138 139 QTreeWidget *loaded_view; 140 QTreeWidget *installed_view; 141 142 QPushButton *load_button; 143 QPushButton *detach_button; 144 145 QStringList prev_packages; 146 147 RKLoadLibsDialog *parent; 148 }; 149 150 /** Item model and encapsulation for package status (used in InstallPackagesWidget) */ 151 class RKRPackageInstallationStatus : public QAbstractItemModel { 152 Q_OBJECT 153 public: 154 explicit RKRPackageInstallationStatus (QObject* parent); 155 ~RKRPackageInstallationStatus (); 156 157 void initialize (RCommandChain *chain); 158 159 enum Columns { 160 EnhancesRKWard, 161 InstallationStatus, 162 PackageName, 163 PackageTitle, 164 Version, 165 Location, 166 COLUMN_COUNT 167 }; 168 enum ToplevelItems { 169 UpdateablePackages, 170 NewPackages, 171 InstalledPackages, 172 TOPLEVELITEM_COUNT 173 }; 174 enum PackageStatusChange { 175 Install, 176 Remove, 177 NoAction 178 }; 179 180 /* Item model implementation */ 181 int rowCount (const QModelIndex &parent = QModelIndex()) const override; columnCount(const QModelIndex &)182 int columnCount (const QModelIndex &) const override { return COLUMN_COUNT; }; 183 QVariant data (const QModelIndex &index, int role=Qt::DisplayRole) const override; 184 QVariant headerData (int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override; 185 Qt::ItemFlags flags (const QModelIndex &index) const override; 186 QModelIndex index (int row, int column, const QModelIndex &parent=QModelIndex()) const override; 187 QModelIndex parent (const QModelIndex &index) const override; 188 bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; 189 190 /** returns a list of packages selected for installation / update */ 191 QStringList packagesToInstall () const; 192 /** fills a list of packages selected for removal, and a parallel list of the locations, from which to remove. 193 * @return true, if any packages are marked for removal, false otherwise. */ 194 bool packagesToRemove (QStringList *packages, QStringList *liblocs); 195 /** mark a package for installation. 196 * @returns the index of the package, if the package is available, an invalid index, if it is not available */ 197 QModelIndex markPackageForInstallation (const QString& package_name); 198 /** mark all available updates for installation. 199 * @returns the index of the "Updateable Packages" item */ 200 QModelIndex markAllUpdatesForInstallation (); 201 /** reset all installation states to NoAction */ 202 void clearStatus (); currentRepositories()203 QStringList currentRepositories () const { return current_repos; }; initialized()204 bool initialized () const { return _initialized; }; 205 private slots: 206 void statusCommandFinished (RCommand *command); 207 private: 208 QStringList available_packages, available_titles, available_versions, available_repos; 209 QStringList installed_packages, installed_titles, installed_versions, installed_libpaths; 210 RData::IntStorage enhance_rk_in_available; 211 RData::IntStorage enhance_rk_in_installed; 212 RData::IntStorage new_packages_in_available; 213 RData::IntStorage updateable_packages_in_available; 214 RData::IntStorage updateable_packages_in_installed; 215 QVector<PackageStatusChange> installed_status; 216 QVector<PackageStatusChange> available_status; 217 QVector<bool> installed_has_update; 218 bool _initialized; 219 220 QStringList current_repos; 221 }; 222 223 class RKRPackageInstallationStatusSortFilterModel : public QSortFilterProxyModel { 224 public: 225 explicit RKRPackageInstallationStatusSortFilterModel (QObject* parent = 0); 226 ~RKRPackageInstallationStatusSortFilterModel (); 227 void setRKWardOnly (bool only); 228 protected: 229 bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; 230 bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const override; 231 bool rkward_only; 232 }; 233 234 /** 235 Allows the user to update / install R packages. 236 To be used in RKLoadLibsDialog. 237 238 @author Thomas Friedrichsmeier 239 */ 240 class InstallPackagesWidget : public QWidget { 241 Q_OBJECT 242 public: 243 explicit InstallPackagesWidget (RKLoadLibsDialog *dialog); 244 245 ~InstallPackagesWidget (); 246 void trySelectPackage (const QString &package_name); 247 void initialize (); 248 public slots: 249 void ok (); 250 void apply (); 251 void cancel (); 252 void filterChanged (); 253 void activated (); 254 void markAllUpdates (); 255 void configureRepositories (); 256 void rowClicked (const QModelIndex& row); 257 private: 258 void doInstall (bool refresh); 259 QTreeView *packages_view; 260 RKRPackageInstallationStatus *packages_status; 261 RKRPackageInstallationStatusSortFilterModel *model; 262 263 QPushButton *mark_all_updates_button; 264 RKDynamicSearchLine *filter_edit; 265 QCheckBox *rkward_packages_only; 266 PackageInstallParamsWidget *install_params; 267 268 RKLoadLibsDialog *parent; 269 }; 270 271 /** 272 Simple helper class for RKLoadLibsDialog to allow selection of installation parameters 273 274 @author Thomas Friedrichsmeier 275 */ 276 class PackageInstallParamsWidget : public QWidget { 277 Q_OBJECT 278 public: 279 explicit PackageInstallParamsWidget (QWidget *parent); 280 281 ~PackageInstallParamsWidget (); 282 283 bool installSuggestedPackages (); 284 QString installLocation (); 285 public slots: 286 void liblocsChanged (const QStringList &newlist); 287 private: 288 QComboBox *libloc_selector; 289 QCheckBox *suggested_packages; 290 }; 291 292 293 #include "../settings/rksettingsmoduleplugins.h" 294 295 class RKPluginMapSelectionWidget : public QWidget { 296 Q_OBJECT 297 public: 298 explicit RKPluginMapSelectionWidget (RKLoadLibsDialog *dialog); 299 virtual ~RKPluginMapSelectionWidget (); 300 public slots: 301 void ok (); 302 void apply (); 303 void cancel (); 304 void activated (); changed()305 void changed () { changes_pending = true; }; 306 private: 307 RKMultiStringSelectorV2* selector; 308 RKSettingsModulePluginsModel* model; 309 bool changes_pending; 310 }; 311 312 #endif 313