/*************************************************************************** * Copyright (C) 2004 by David Sansome * * me@davidsansome.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "wizard.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "data.h" #include "rcparser.h" #include "headerlistitem.h" typedef TQValueVector CompileErrorVector; CompileErrorVector errs( 5 ); // vector of 3 Employees ComponentListItem::ComponentListItem(struct Component c, TQListView* parent) : TQCheckListItem(parent, "", TQCheckListItem::CheckBox) { component = c; setText(0, c.niceName); setOn(true); if (c.gnomeOnly) section=2; else if (c.kdeOnly) section=3; else if (c.optional) section=1; else section=0; } int ComponentListItem::compare(TQListViewItem* i, int col, bool ascending) const { switch (i->rtti()) { case 1001: // Component { ComponentListItem* item = (ComponentListItem*) i; if (section < item->section) return -1; if (section > item->section) return 1; return TQListViewItem::compare(i, col, ascending); } break; case 1002: // Header { HeaderListItem* item = (HeaderListItem*) i; if (section < item->section) return -1; return 1; } break; } return 0; } Wizard::Wizard(TQWidget *parent, const char *name) : WizardBase(parent, name, false, WDestructiveClose) { componentInfo->setMaximumSize(32767,70); componentList->header()->hide(); //progressLabel2->setMaximumSize(32767, progressLabel2->fontMetrics().height()*2); externalProcess = new TQProcess(this); connect(externalProcess, SIGNAL(processExited()), SLOT(processExited())); connect(externalProcess, SIGNAL(readyReadStdout()), SLOT(readyReadStdout())); connect(externalProcess, SIGNAL(readyReadStderr()), SLOT(readyReadStderr())); logDialog = new LogDialog(this); logDialog->hide(); previousButton->hide(); createActionFormats(); kdeDirProcess = new TQProcess(this); connect(kdeDirProcess, SIGNAL(readyReadStdout()), SLOT(kdeDirReady())); connect(kdeDirProcess, SIGNAL(processExited()), SLOT(getInstalledComponents())); kdeDirProcess->addArgument("tde-config"); kdeDirProcess->addArgument("--prefix"); if (!kdeDirProcess->start()) getInstalledComponents(); errs[0] = CompileError( "libevent", "The installation process finished with an error because it needs a " " component missing on your system. To correct this, " "do the following:
1. Download and install the package for your distribution with the word 'libevent' in its title.
2. Retry installation." ); errs[1] = CompileError( "X includes", "The installation process finished with an error because it needs a " " component missing on your system. To correct this, " "do the following:
1. Download and install any packages for your distribution with (i) 'X' and " " either 'devel' or 'lib' in their name.
2. Retry installation. " ); errs[2] = CompileError( "There is no user 'privoxy' on this system", "The installation reported an" "error because you need to create the 'privoxy' user. To correct this, " "do the following:
1. As root, enter the following command: useradd privoxy.
2. Retry installation. " ); errs[3] = CompileError( "installing config files as root", "The installation reported an" "error because I attempted to install the privoxy config files as root. There is no " "need to take any action on your part. Privoxy has been installed and you can now use it with TorK. " ); errs[4] = CompileError( "TQt (>= ", "The installation process finished with an error because it needs a " " component missing on your system. To correct this, " "do the following:
1. Download and install any packages for your distribution with (i) 'qt' and " " either 'devel' or 'lib' in their name.
2. Retry installation. " ); } void Wizard::createActionFormats() { // Taken from KDevelop actionFormats.clear(); actionFormats.append(ActionFormat( tr("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "gcc", "gcc\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "gcc", "gcc\\S* (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "unknown", "^compiling (.*)", 1 )); actionFormats.append(ActionFormat( tr("generating"), "moc", "/moc\\b.*\\s-o\\s([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("generating"), "uic", "/uic\\b.*\\s-o\\s([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("linking"), "libtool", "/+bin/+sh\\s.*libtool.*--mode=link\\s.*\\s-o\\s([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("linking"), "g++", "g\\+\\+\\S* (?:\\S* )*-o ([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("linking"), "gcc", "gcc\\S* (?:\\S* )*-o ([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("creating"), "", "/(?:bin/+sh\\s.*mkinstalldirs).*\\s([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("installing"), "", "/(?:usr/+bin/+install|bin/+sh\\s.*mkinstalldirs|bin/+sh\\s.*libtool.*--mode=install).*\\s\\'?([^\\s;\\']+)\\'?", 1 )); actionFormats.append(ActionFormat( tr("generating"), "dcopidl", "dcopidl .* > ([^\\s;]+)", 1 )); actionFormats.append(ActionFormat( tr("compiling"), "dcopidl2cpp", "dcopidl2cpp (?:\\S* )*([^\\s;]+)", 1 )); } void Wizard::kdeDirReady() { while (kdeDirProcess->canReadLineStdout()) { TQString line = kdeDirProcess->readLineStdout(); if (!line.isEmpty()) kdeDir = line; } } void Wizard::getInstalledComponents() { TQFile uninstallScript("/tmp/arkollon-uninstall.sh"); if (uninstallScript.exists()) uninstallScript.remove(); uninstallScript.open(IO_WriteOnly); TQDataStream stream(&uninstallScript); stream.writeRawBytes((const char*)uninstaller_sh_data, uninstaller_sh_len); uninstallScript.close(); installedComponentsProcess = new TQProcess(this); connect(installedComponentsProcess, SIGNAL(readyReadStdout()), SLOT(installedComponentsReady())); connect(installedComponentsProcess, SIGNAL(processExited()), SLOT(setup())); installedComponentsProcess->addArgument("/bin/sh"); installedComponentsProcess->addArgument("/tmp/arkollon-uninstall.sh"); installedComponentsProcess->addArgument("--list"); if (!installedComponentsProcess->start()) setup(); } void Wizard::installedComponentsReady() { while (installedComponentsProcess->canReadLineStdout()) { TQString line = installedComponentsProcess->readLineStdout(); if (line.isEmpty()) continue; // See if it already exists if (installedComponents.find(line.lower()) != installedComponents.end()) continue; installedComponents.append(line.lower()); //printf("Found installed component %s\n", parser.cap(3).latin1()); } } void Wizard::setup() { TQFile uninstallScript("/tmp/arkollon-uninstall.sh"); if (uninstallScript.exists()) uninstallScript.remove(); if (kdeDir.isEmpty()) kdeDir = "/usr"; // Firstly check if there's an arkollonrc file in the current directory // If there is, use it. dir = TQDir::currentDirPath(); if (tqApp->argc() > 1) { // The directory specified on the command line overrides the current dir. TQDir d(tqApp->argv()[1]); dir = d.absPath(); } if (TQFile::exists(dir + "/arkollonrc")) { setupFromRc(); } else { if (!setupFromDir()) { TQMessageBox::critical(NULL, "Error", "This directory does not contain any recognised buildsystem", TQMessageBox::Ok, TQMessageBox::NoButton, TQMessageBox::NoButton); reject(); return; } } show(); } void Wizard::setupFromRc() { RcParser parser; parser.addSearchDir(dir); if (!parser.openFile("arkollonrc")) { TQMessageBox::critical(NULL, "Error", "The \"arkollonrc\" file in this directory could not be read", TQMessageBox::Ok, TQMessageBox::NoButton, TQMessageBox::NoButton); reject(); return; } parser.setSection("Arkollon"); TQString appName = parser.readString("AppName"); if (appName.isEmpty()) { TQMessageBox::critical(NULL, "Error", "The \"arkollonrc\" file in this directory contains no application name!", TQMessageBox::Ok, TQMessageBox::NoButton, TQMessageBox::NoButton); reject(); return; } setAppName(appName); TQString icon32Path = parser.readString("Icon32"); TQString icon16Path = parser.readString("Icon16"); if ((!icon32Path.isEmpty()) && (TQFile::exists(dir + "/" + icon32Path))) { TQPixmap icon32(dir + "/" + icon32Path); appIcon->setPixmap(icon32); } if ((!icon16Path.isEmpty()) && (TQFile::exists(dir + "/" + icon16Path))) { TQPixmap icon16(dir + "/" + icon16Path); setIcon(icon16); } buildOrder = parser.readList("BuildOrder"); TQStringList compNames = parser.readList("Components"); TQStringList::Iterator it = compNames.begin(); while( it != compNames.end() ) { parser.setSection(*it); struct Component c; c.name = *it; c.niceName = parser.readString("NiceName"); c.subDir = parser.readString("SubDir"); c.forceDir = sub(parser.readString("ForceDir")); c.optional = parser.readBool("Optional", false); c.kdeOnly = parser.readBool("TDEOnly", false); c.gnomeOnly = parser.readBool("GnomeOnly", false); c.description = sub(parser.readString("Description")); c.confOptions = parser.readString("ConfigureOptions"); c.alreadyInstalled = false; // Load the buildtimes data if (TQFile::exists(dir + "/" + c.subDir + "/buildtimes")) { TQRegExp re("([^,]*,[^,]*),(\\d*)"); TQFile file(dir + "/" + c.subDir + "/buildtimes"); file.open(IO_ReadOnly); TQTextStream stream(&file); for (;;) { TQString line = stream.readLine(); if (line.isNull()) break; if (re.search(line) == -1) continue; c.buildTimes.insert(re.cap(1), re.cap(2).toInt()); } } // Add the header for this component ComponentListItem* item = new ComponentListItem(c, componentList); if (!headers.contains(item->section)) { headers[item->section] = new HeaderListItem(componentList); ((HeaderListItem*)headers[item->section])->section = item->section; switch(item->section) { case 0: headers[item->section]->setText(0, "Required components"); break; case 1: headers[item->section]->setText(0, "Optional components"); break; case 2: headers[item->section]->setText(0, "Gnome specific components"); break; case 3: headers[item->section]->setText(0, "TDE specific components"); break; } } // Check if it's already installed TQStringList::Iterator it2 = installedComponents.begin(); while( it2 != installedComponents.end() ) { int dashPos = c.subDir.findRev('-'); if (dashPos < 0) dashPos = c.subDir.length(); TQString version = c.subDir.left(dashPos) + ":" + c.subDir.right(c.subDir.length() - dashPos - 1); if (*it2 == version.lower()) { item->setOn(false); item->component.alreadyInstalled = true; } ++it2; } ++it; } parser.setSection("Arkollon"); exec = sub(parser.readString("Exec")); desktop = sub(parser.readString("Desktop")); } bool Wizard::setupFromDir() { if ((!TQFile::exists(dir + "/configure")) && (!TQFile::exists(dir + "/autogen.sh")) && (!TQFile::exists(dir + "/auto-gen.sh"))) { TQDir myDir(dir + "/" + selectedComponents[currentComponent].subDir); if (myDir.entryList("*.pro", TQDir::Files).count() <= 0) return false; } // Use the directory name as the appname TQDir myDir2(dir); TQString dirName = myDir2.dirName(); setAppName(makeDirNice(dirName)); buildOrder.append(dirName); struct Component c; c.name = dirName; c.niceName = makeDirNice(dirName); c.optional = false; c.subDir = ""; c.gnomeOnly = false; c.kdeOnly = false; c.description = "No description is associated with this component."; c.alreadyInstalled = false; ComponentListItem* item = new ComponentListItem(c, componentList); HeaderListItem* header = new HeaderListItem(componentList); header->setText(0, "Required components"); header->section = 0; TQStringList::Iterator it2 = installedComponents.begin(); while( it2 != installedComponents.end() ) { int dashPos = dirName.findRev('-'); if (dashPos < 0) dashPos = dirName.length(); TQString version = dirName.left(dashPos) + ":" + dirName.right(dirName.length() - dashPos - 1); if (*it2 == version.lower()) item->component.alreadyInstalled = true; ++it2; } return true; } Wizard::~Wizard() { } void Wizard::componentSelected(TQListViewItem* item) { if (item->rtti() != 1001) return; ComponentListItem* i = (ComponentListItem*) item; TQString text = "

" + item->text(0) + ""; if (i->component.alreadyInstalled) text += " (Already installed)"; text += "

"; text += i->component.description; text += "

"; componentInfo->setText(text); } TQString Wizard::makeDirNice(TQString name) { int dashPos = name.findRev('-'); if (dashPos < 0) dashPos = name.length(); TQString ret = name.left(dashPos); ret = ret.left(1).upper() + ret.right(ret.length()-1); return ret; } void Wizard::cancelPressed() { if (externalProcess->isRunning()) externalProcess->tryTerminate(); reject(); } void Wizard::nextPressed() { int currentId = installStack->id(installStack->visibleWidget()); if (currentId == 3) { TQDir d(kdeDir); d.mkdir("share/apps/kdesktop/Desktop"); if (shortcutBox->isChecked()) { TQFile source(dir + "/" + desktop); TQString destDir = kdeDir + "/share/apps/kdesktop/Desktop"; int slashPos = desktop.findRev('/'); if (slashPos < 0) slashPos = 0; TQFile dest(destDir + "/" + desktop.right(desktop.length() - slashPos)); source.open(IO_ReadOnly); dest.open(IO_WriteOnly | IO_Truncate); TQDataStream destStream(&dest); TQByteArray data = source.readAll(); destStream.writeRawBytes(data.data(), data.size()); source.close(); dest.close(); } if (uninstallBox->isChecked()) { TQFile source(dir + "/Uninstall TorK.desktop"); TQFile dest(kdeDir + "/share/apps/kdesktop/Desktop/Uinstall TorK.desktop"); source.open(IO_ReadOnly); dest.open(IO_WriteOnly | IO_Truncate); TQDataStream destStream(&dest); TQByteArray data = source.readAll(); destStream.writeRawBytes(data.data(), data.size()); source.close(); dest.close(); } accept(); return; } if ((currentId == 2) && (exec.isEmpty())) { accept(); return; } if (currentId == 1) { bool itemsSelected = false; TQListViewItemIterator it( componentList ); while ( it.current() ) { if (it.current()->rtti() != 1001) { ++it; continue; } ComponentListItem* item = (ComponentListItem*) it.current(); if (item->isOn()) itemsSelected = true; ++it; } if (!itemsSelected) { TQMessageBox::warning(this, "Warning", "You need to select at least one component", TQMessageBox::Ok, TQMessageBox::NoButton, TQMessageBox::NoButton); return; } } installStack->raiseWidget(++currentId); if (currentId == 2) { pleaseWaitLabel->setText("Please wait while the software is compiled and installed"); timeRemaining->setText("Estimated time remaining: Calculating..."); startProcess(); nextButton->setEnabled(false); previousButton->setEnabled(false); } else if (currentId == 3) { nextButton->setText("Finish"); } else previousButton->setEnabled(true); } void Wizard::previousPressed() { int currentId = installStack->id(installStack->visibleWidget()); if (currentId == 0) return; installStack->raiseWidget(--currentId); if (currentId == 0) previousButton->setEnabled(false); nextButton->setEnabled(true); } void Wizard::startProcess() { selectedComponents.clear(); totalBTime = 0; elapsedTime = 0; elapsedBTime = 0; for ( TQStringList::Iterator it = buildOrder.begin(); it != buildOrder.end(); ++it ) { TQListViewItemIterator it2( componentList ); while ( it2.current() ) { if (it2.current()->rtti() != 1001) { ++it2; continue; } ComponentListItem* item = (ComponentListItem*) it2.current(); if (item->component.name == *it) { if (item->isOn()) { selectedComponents.append(item->component); TQMap::iterator it3; for ( it3 = item->component.buildTimes.begin(); it3 != item->component.buildTimes.end(); ++it3 ) totalBTime += it3.data(); } } ++it2; } } progressBar->setProgress(0); progressBar->setTotalSteps(totalBTime); currentComponent = 0; currentStage = None; currentIsTQMake = false; nextStep(); } void Wizard::nextStep() { externalProcess->clearArguments(); switch (currentStage) { case None: { logLine(selectedComponents[currentComponent].niceName); progressLabel1->setText("Running autogen for " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); //progressLabel2->setCursorPosition(0); currentStage = Autogen; TQDir myDir(dir + "/" + selectedComponents[currentComponent].subDir); if (myDir.entryList("*.pro", TQDir::Files).count() > 0) { currentIsTQMake = true; nextStep(); return; } if (TQFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/configure")) { nextStep(); return; } TQString autogenName; if (TQFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/autogen.sh")) autogenName = "autogen.sh"; else if (TQFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/auto-gen.sh")) autogenName = "auto-gen.sh"; else { logLine("No configure, autogen, or qmake scripts found"); errorOccured(); return; } externalProcess->addArgument(dir + "/" + selectedComponents[currentComponent].subDir + autogenName); externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir); logLine("Running autogen..."); externalProcess->start(); break; } case Autogen: { //progressBar->setProgress(progressBar->progress() + 1); currentStage = Configure; if (currentIsTQMake) { progressLabel1->setText("Running qmake for " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); //progressLabel2->setCursorPosition(0); externalProcess->addArgument("qmake"); externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir); if (!externalProcess->start()) { logLine("Error: qmake was not found. Try installing the TQt-devel libraries."); errorOccured(); return; } logLine("Running qmake..."); break; } if (!selectedComponents[currentComponent].forceDir.isEmpty()) prefix = selectedComponents[currentComponent].forceDir; else prefix = "/usr/local"; externalProcess->addArgument("./configure"); //externalProcess->addArgument("--prefix=" + prefix); if (!selectedComponents[currentComponent].confOptions.isEmpty()) { TQStringList extraArgs = TQStringList::split(" ", sub(selectedComponents[currentComponent].confOptions)); for ( TQStringList::Iterator it = extraArgs.begin(); it != extraArgs.end(); ++it ) externalProcess->addArgument(*it); } externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir); logLine("Running configure (" + externalProcess->arguments().join(" ") + ")..."); progressLabel1->setText("Configuring " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); timer.start(); externalProcess->start(); break; } case Configure: { updateTime("configure,"); currentStage = Compile; externalProcess->addArgument("make"); externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir); logLine("Running make..."); progressLabel1->setText("Compiling " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); timer.setHMS(0, 0, 0); externalProcess->start(); break; } case Compile: { currentStage = Install; logLine("Installing..."); progressLabel1->setText("Installing " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); installedFiles.clear(); externalProcess->addArgument("make"); externalProcess->addArgument("install"); externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir); externalProcess->start(); break; } case Install: { currentStage = WriteUninstallInfo; logLine("Writing uninstall information..."); progressLabel1->setText("Writing uninstall information for " + selectedComponents[currentComponent].niceName + ""); setProgress2Text(""); TQFile postInstallScript("/tmp/arkollon-postinstall.sh"); if (postInstallScript.exists()) postInstallScript.remove(); postInstallScript.open(IO_WriteOnly); TQDataStream stream(&postInstallScript); stream.writeRawBytes((const char*)postinstall_sh_data, postinstall_sh_len); postInstallScript.close(); TQFile fileList("/tmp/arkollon-filelist"); if (fileList.exists()) fileList.remove(); fileList.open(IO_WriteOnly); TQTextStream fileStream(&fileList); TQStringList doneFiles; for ( TQStringList::Iterator it = installedFiles.begin(); it != installedFiles.end(); ++it ) { if (doneFiles.find(*it) != doneFiles.end()) continue; TQFileInfo fileInfo(*it); if (fileInfo.isDir()) continue; fileStream << (*it) << '\n'; doneFiles.append(*it); } fileList.close(); struct Component c = selectedComponents[currentComponent]; int dashPos = c.subDir.findRev('-'); if (dashPos < 0) dashPos = c.subDir.length(); TQString appname = c.subDir.left(dashPos); TQString version = c.subDir.right(c.subDir.length() - dashPos - 1); externalProcess->addArgument("/bin/sh"); externalProcess->addArgument("/tmp/arkollon-postinstall.sh"); externalProcess->addArgument("--appname"); externalProcess->addArgument(appname); externalProcess->addArgument("--version"); externalProcess->addArgument(version); externalProcess->addArgument("--filelist"); externalProcess->addArgument("/tmp/arkollon-filelist"); externalProcess->start(); break; } case WriteUninstallInfo: { currentStage = None; currentComponent++; currentIsTQMake = false; if (currentComponent >= selectedComponents.count()) { progressLabel1->setText("Installation completed!"); pleaseWaitLabel->setText("Installation complete"); timeRemaining->setText(""); progressBar->setProgress(totalBTime); nextButton->setEnabled(true); if (exec.isEmpty()) { nextButton->setText("Finish"); setProgress2Text(""); } else { setProgress2Text("Click \"next\" to continue"); } return; } nextStep(); break; } default: break; } } void Wizard::processExited() { if (currentStage == WriteUninstallInfo) { // Remove temp files from the last stage TQFile postInstallScript("/tmp/arkollon-postinstall.sh"); if (postInstallScript.exists()) postInstallScript.remove(); TQFile fileList("/tmp/arkollon-filelist"); if (fileList.exists()) fileList.remove(); } if (!externalProcess->normalExit()) { logLine("Process was killed"); errorOccured(); return; } if (externalProcess->exitStatus() != 0) { logLine("Return value " + TQString::number(externalProcess->exitStatus())); errorOccured(); return; } if (currentStage == Compile) updateTime(lastTimeLine); nextStep(); } void Wizard::readyReadStderr() { while (externalProcess->canReadLineStderr()) { TQString line = externalProcess->readLineStderr().latin1(); CompileErrorVector::iterator it; for( it = errs.begin(); it != errs.end(); ++it ){ if (line.contains((*it).type())) TQMessageBox::information( this, (*it).type(), (*it).message() ); } logDialog->logBox->append(" * "+line); } } void Wizard::readyReadStdout() { while (externalProcess->canReadLineStdout()) { TQString line = externalProcess->readLineStdout().latin1(); logDialog->logBox->append(line); if (currentStage == Configure) { setProgress2Text(line); continue; } commandLine += line; if (line.right(1) == "\\") continue; commandLine = commandLine.left(commandLine.find(';')); for ( TQValueList::Iterator it = actionFormats.begin(); it != actionFormats.end(); ++it ) { if ((*it).regExp.search(commandLine) == -1) continue; setProgress2Text((*it).action + " " + (*it).regExp.cap(1) + " (" + (*it).tool + ")"); if ((currentStage == Install) && ((*it).action == "installing")) installedFiles.append((*it).regExp.cap(1)); else updateTime(lastTimeLine); lastTimeLine = (*it).tool + "," + (*it).regExp.cap(1); } commandLine = ""; } } void Wizard::updateTime(TQString key) { if (!timer.isNull()) { elapsedBTime += selectedComponents[currentComponent].buildTimes[key]; elapsedTime += timer.elapsed(); float ratio = (float)elapsedTime / (float)elapsedBTime; int remainingTime = (int)((float)(totalBTime - elapsedBTime) * ratio) / 60000; if (remainingTime < 0) remainingTime = 0; TQString text = TQString::number(remainingTime + 1) + " minutes"; if (remainingTime == 0) text = "1 minute"; timeRemaining->setText("Estimated time remaining: " + text + ""); progressBar->setProgress(elapsedBTime); } timer.start(); } void Wizard::logLine(TQString line) { TQString tmp = line; TQStringList lines = TQStringList::split("\n", tmp); for ( TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) { if ((*it).isEmpty()) continue; logDialog->logBox->append("***** "+*it); } } void Wizard::setProgress2Text(TQString text) { TQString croppedText = text; int i = croppedText.length(); TQFont boldFont = progressLabel2->font(); boldFont.setBold(true); TQFontMetrics boldFontMetrics(boldFont); while (boldFontMetrics.width(croppedText) > progressLabel2->width()) { croppedText = croppedText.left(--i); } progressLabel2->setText(croppedText); } void Wizard::errorOccured() { //logFrame->show(); pleaseWaitLabel->setText("An error occured"); progressLabel1->setText("An error occured"); setProgress2Text("See the log file for more information"); previousButton->setEnabled(true); } TQString Wizard::sub(TQString s) { TQString tmp = s; tmp.replace(TQRegExp("\\$TDEDIR"), kdeDir); tmp.replace(TQRegExp("\\$HOMEDIR"), TQDir::homeDirPath()); tmp.replace(TQRegExp("~"), TQDir::homeDirPath()); tmp.replace(TQRegExp("\\$PREFIX"), "/usr/local"); return tmp; } void Wizard::runPressed() { TQProcess* proc = new TQProcess(this); proc->addArgument(exec); if (!proc->start()) { TQMessageBox::warning(this, "Warning", "The application could not be started
"+exec, TQMessageBox::Ok, TQMessageBox::NoButton, TQMessageBox::NoButton); } } void Wizard::logPressed() { logDialog->show(); } #include "wizard.moc"