void AbstractRepository::process(Job *job, const QList<InstallOperation *> &install_, DWORD programCloseType, bool printScriptOutput, bool interactive) { QDir d; QList<InstallOperation *> install = install_; // reoder the operations if a package is updated. In this case it is better // to uninstall the old first and then install the new one. if (install.size() == 2) { InstallOperation* first = install.at(0); InstallOperation* second = install.at(1); if (first->package == second->package && first->install && !second->install) { install.insert(0, second); install.removeAt(2); } } // search for PackageVersion objects QList<PackageVersion*> pvs; for (int i = 0; i < install.size(); i++) { InstallOperation* op = install.at(i); QString err; PackageVersion* pv = op->findPackageVersion(&err); if (!err.isEmpty()) { job->setErrorMessage(QString( QObject::tr("Cannot find the package version %1 %2: %3")). arg(op->package). arg(op->version.getVersionString()). arg(err)); break; } if (!pv) { job->setErrorMessage(QString( QObject::tr("Cannot find the package version %1 %2")). arg(op->package). arg(op->version.getVersionString())); break; } pvs.append(pv); } if (job->shouldProceed()) { for (int j = 0; j < pvs.size(); j++) { PackageVersion* pv = pvs.at(j); pv->lock(); } } int n = install.count(); // where the binary was downloaded QStringList dirs; // names of the binaries relative to the directory QStringList binaries; // 70% for downloading the binaries if (job->shouldProceed()) { // downloading packages for (int i = 0; i < install.count(); i++) { InstallOperation* op = install.at(i); PackageVersion* pv = pvs.at(i); if (op->install) { QString txt = QObject::tr("Downloading %1").arg( pv->toString()); Job* sub = job->newSubJob(0.7 / n, txt, true, true); // dir is not the final installation directory. It can be // changed later during the installation. QString dir = op->where; if (dir.isEmpty()) { dir = pv->getIdealInstallationDirectory(); } dir = WPMUtils::findNonExistingFile(dir, ""); if (d.exists(dir)) { sub->setErrorMessage( QObject::tr("Directory %1 already exists"). arg(dir)); dirs.append(""); binaries.append(""); } else { dirs.append(dir); QString binary = pv->download_(sub, dir, interactive); binaries.append(QFileInfo(binary).fileName()); } } else { dirs.append(""); binaries.append(""); job->setProgress(job->getProgress() + 0.7 / n); } if (!job->shouldProceed()) break; } } // 10% for stopping the packages if (job->shouldProceed()) { for (int i = 0; i < install.count(); i++) { InstallOperation* op = install.at(i); PackageVersion* pv = pvs.at(i); if (!op->install) { Job* sub = job->newSubJob(0.1 / n, QObject::tr("Stopping the package %1 of %2"). arg(i + 1).arg(n)); pv->stop(sub, programCloseType, printScriptOutput); if (!sub->getErrorMessage().isEmpty()) { job->setErrorMessage(sub->getErrorMessage()); break; } } else { job->setProgress(job->getProgress() + 0.1 / n); } } } int processed = 0; // 19% for removing/installing the packages if (job->shouldProceed()) { // installing/removing packages for (int i = 0; i < install.count(); i++) { InstallOperation* op = install.at(i); PackageVersion* pv = pvs.at(i); QString txt; if (op->install) txt = QString(QObject::tr("Installing %1")).arg( pv->toString()); else txt = QString(QObject::tr("Uninstalling %1")).arg( pv->toString()); Job* sub = job->newSubJob(0.19 / n, txt, true, true); if (op->install) { QString dir = dirs.at(i); QString binary = binaries.at(i); if (op->where.isEmpty()) { // if we are not forced to install in a particular // directory, we try to use the ideal location QString try_ = pv->getIdealInstallationDirectory(); if (WPMUtils::pathEquals(try_, dir) || (!d.exists(try_) && d.rename(dir, try_))) { dir = try_; } else { try_ = pv->getSecondaryInstallationDirectory(); if (WPMUtils::pathEquals(try_, dir) || (!d.exists(try_) && d.rename(dir, try_))) { dir = try_; } else { try_ = WPMUtils::findNonExistingFile(try_, ""); if (WPMUtils::pathEquals(try_, dir) || (!d.exists(try_) && d.rename(dir, try_))) { dir = try_; } } } } else { if (d.exists(op->where)) { if (!WPMUtils::pathEquals(op->where, dir)) { // we should install in a particular directory, but it // exists. Job* djob = sub->newSubJob(1, QObject::tr("Deleting temporary directory %1"). arg(dir)); QDir ddir(dir); WPMUtils::removeDirectory(djob, ddir); job->setErrorMessage(QObject::tr( "Cannot install %1 into %2. The directory already exists."). arg(pv->toString(true)).arg(op->where)); break; } } else { if (d.rename(dir, op->where)) dir = op->where; else { // we should install in a particular directory, but it // exists. Job* djob = sub->newSubJob(1, QObject::tr("Deleting temporary directory %1"). arg(dir)); QDir ddir(dir); WPMUtils::removeDirectory(djob, ddir); job->setErrorMessage(QObject::tr( "Cannot install %1 into %2. Cannot rename %3."). arg(pv->toString(true), op->where, dir)); break; } } } pv->install(sub, dir, binary, printScriptOutput, programCloseType); } else pv->uninstall(sub, printScriptOutput, programCloseType); if (!job->shouldProceed()) break; processed = i + 1; } } // removing the binaries if we should not proceed if (!job->shouldProceed()) { for (int i = processed; i < dirs.count(); i++) { QString dir = dirs.at(i); if (!dir.isEmpty()) { QString txt = QObject::tr("Deleting %1").arg(dir); Job* sub = job->newSubJob(0.01 / dirs.count(), txt, true, false); QDir ddir(dir); WPMUtils::removeDirectory(sub, ddir); } else { job->setProgress(job->getProgress() + 0.01 / dirs.count()); } } } for (int j = 0; j < pvs.size(); j++) { PackageVersion* pv = pvs.at(j); pv->unlock(); } qDeleteAll(pvs); if (job->shouldProceed()) job->setProgress(1); job->complete(); }
void SettingsFrame::on_buttonBox_clicked(QAbstractButton *button) { MainWindow* mw = MainWindow::getInstance(); if (mw->hardDriveScanRunning) { mw->addErrorMessage(QObject::tr("Cannot change settings now. The hard drive scan is running.")); return; } QString err; PackageVersion* locked = PackageVersion::findLockedPackageVersion(&err); if (locked) { err = QObject::tr("Cannot find locked package versions: %1"). arg(err); mw->addErrorMessage(err); delete locked; return; } if (locked) { QString msg(QObject::tr("Cannot change settings now. The package %1 is locked by a currently running installation/removal.")); mw->addErrorMessage(msg.arg(locked->toString())); delete locked; return; } QStringList list = getRepositoryURLs(); if (err.isEmpty() && list.count() == 0) err = QObject::tr("No repositories defined"); if (err.isEmpty()) { err = WPMUtils::checkInstallationDirectory(getInstallationDirectory()); } QList<QUrl*> urls; if (err.isEmpty()) { for (int i = 0; i < list.count(); i++) { QUrl* url = new QUrl(list.at(i)); urls.append(url); if (!url->isValid()) { err = QString(QObject::tr("%1 is not a valid repository address")).arg( list.at(i)); break; } } } if (err.isEmpty()) { WPMUtils::setInstallationDirectory(getInstallationDirectory()); WPMUtils::setCloseProcessType(getCloseProcessType()); } bool repsChanged = false; if (err.isEmpty()) { QList<QUrl*> oldList = Repository::getRepositoryURLs(&err); repsChanged = oldList.count() != urls.count(); if (!repsChanged) { for (int i = 0; i < oldList.count(); i++) { if ((*oldList.at(i)) != (*urls.at(i))) { repsChanged = true; break; } } } qDeleteAll(oldList); oldList.clear(); } if (err.isEmpty()) { if (repsChanged) { if (mw->reloadRepositoriesThreadRunning) { err = QObject::tr("Cannot change settings now. The repositories download is running."); } else { Repository::setRepositoryURLs(urls, &err); if (err.isEmpty()) { mw->closeDetailTabs(); mw->recognizeAndLoadRepositories(false); } } } } qDeleteAll(urls); urls.clear(); if (err.isEmpty()) { WindowsRegistry m(HKEY_LOCAL_MACHINE, false, KEY_ALL_ACCESS); WindowsRegistry wr = m.createSubKey( "Software\\Npackd\\Npackd\\InstallationDirs", &err, KEY_ALL_ACCESS); QStringList dirs; for (int i = 0; i < this->ui->comboBoxDir->count(); i++) dirs.append(this->ui->comboBoxDir->itemText(i)); if (err.isEmpty()) { wr.saveStringList(dirs); } // it is not important, whether the list of directories is saved or not err = ""; } if (!err.isEmpty()) mw->addErrorMessage(err, err, true, QMessageBox::Critical); }