source: src-qt4/pc-installgui/installer.cpp @ 027bbae

9.2-releasereleng/10.0releng/10.0.1
Last change on this file since 027bbae was 027bbae, checked in by Kris Moore <kris@…>, 12 months ago

Setup pc-installgui to switch between the default pc-sysinstall and a debug copy, if it exists

  • Property mode set to 100644
File size: 50.7 KB
RevLine 
[1620346]1#include <QCloseEvent>
2#include <QProcess>
3#include <QTimer>
4#include <QTranslator>
5#include <QGraphicsPixmapItem>
6
7#include "backend.h"
8#include "installer.h"
9#include "helpText.h"
10
11Installer::Installer(QWidget *parent) : QMainWindow(parent)
12{
13    setupUi(this);
14    translator = new QTranslator();
15    haveWarnedSpace=false;
16
17    connect(abortButton, SIGNAL(clicked()), this, SLOT(slotAbort()));
18    connect(backButton, SIGNAL(clicked()), this, SLOT(slotBack()));
19    connect(nextButton, SIGNAL(clicked()), this, SLOT(slotNext()));
20
21    connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
22    connect(pushTouchKeyboard, SIGNAL(clicked()), this, SLOT(slotPushVirtKeyboard()));
23    connect(pushChangeKeyLayout, SIGNAL(clicked()), this, SLOT(slotPushKeyLayout()));
24    connect(pushHardware, SIGNAL(clicked()), this, SLOT(slotCheckHardware()));
25
26    abortButton->setText(tr("&Cancel"));
27    backButton->setText(tr("&Back"));
28    nextButton->setText(tr("&Next"));
29
30    // Init the MBR to yes
31    loadMBR = true;
32    // Init the GPT to no
33    loadGPT = false;
34
35    // No optional components by default
36    fSRC=false;
37    fPORTS=false;
38
39    // Load the keyboard info
40    keyModels = Scripts::Backend::keyModels();
41    keyLayouts = Scripts::Backend::keyLayouts();
42
43    // Set the arch name
44    setArch();
45
46    // Start on the first screen
47    installStackWidget->setCurrentIndex(0);
48    backButton->setVisible(false);
49}
50
51Installer::~Installer()
52{
53    //delete ui;
54}
55
56bool Installer::isInstalled()
57{
58    return false;
59}
60
61void Installer::setArch()
62{
63   QProcess m;
64   m.start(QString("uname"), QStringList() << "-m");
65   while(m.state() == QProcess::Starting || m.state() == QProcess::Running) {
66      m.waitForFinished(200);
67      QCoreApplication::processEvents();
68   }
69
70   // Get output
71   Arch = m.readLine().simplified();
72   qDebug() << Arch;
73}
74
75void Installer::slotCheckHardware()
76{
77  pcHardware = new dialogCheckHardware();
78  pcHardware->programInit();
79  pcHardware->setWindowModality(Qt::ApplicationModal);
80  pcHardware->show();
81  pcHardware->raise();
82}
83
84void Installer::slotPushKeyLayout()
85{
86  wKey = new widgetKeyboard();
87  wKey->programInit(keyModels, keyLayouts);
88  wKey->setWindowModality(Qt::ApplicationModal);
89  wKey->show();
90  wKey->raise();
91}
92
93void Installer::initInstall()
94{
95    // load languages
96    comboLanguage->clear();
97    languages = Scripts::Backend::languages();
98    for (int i=0; i < languages.count(); ++i) {
99        QString languageStr = languages.at(i);
100        QString language = languageStr.split("-").at(0);
101        comboLanguage->addItem(language.trimmed());
102    }
103    connect(comboLanguage, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeLanguage()));
104
105    // Load any package scheme data
106    listDeskPkgs = Scripts::Backend::getPackageData(availDesktopPackageData, QString());
107    listServerPkgs = Scripts::Backend::getPackageData(availServerPackageData, QString("trueos"));
108
109    // Do check for available meta-pkgs on boot media
110    if ( QFile::exists("/tmp/no-meta-pkgs") )
111        hasPkgsOnMedia = false;
112    else
113        hasPkgsOnMedia = true;
114
115    qDebug() << "Package Media:" << availDesktopPackageData << hasPkgsOnMedia;
116
117    // See if this media has a freebsd release on it
118    if ( QFile::exists("/tmp/no-fbsd-release") ) {
119        hasFreeBSDOnMedia = false;
120    } else {
121        hasFreeBSDOnMedia = true;
122    }
123       
124    // Do check for install pkgs on boot media
125    if ( QFile::exists("/tmp/no-install-pkgs") ) {
126        hasInstallOnMedia = false;
127    } else {
128        hasInstallOnMedia = true;
129    }
130
131    // Set the key toggle
132    toggleKeyLayout = true;
133
134    // Is this a LIVE disk?
135    if ( QFile::exists("/usr/pcbsd-live") )
136        isLiveMode = true;
137    else
138        isLiveMode = false;
139
140    // Get available memory
141    systemMemory = Scripts::Backend::systemMemory();
142
143    // Load up the keyboard information
144    //connectKeyboardSlots();
145
146    // Connect the disk slots
147    connect(pushDiskCustomize,SIGNAL(clicked()), this, SLOT(slotDiskCustomizeClicked()));
148
149    // Load the disks
150    loadDiskInfo();
151   
152
153    // Init the desktop wheel
154    initDesktopSelector();
155}
156
157void Installer::loadDiskInfo()
158{
159   sysDisks = Scripts::Backend::hardDrives();
160   if ( sysDisks.empty() ) {
161      QMessageBox::critical(this, tr("PC-BSD Installer"),
162                                tr("Unable to detect any disk drives! The install will now exit."),
163                                QMessageBox::Ok,
164                                QMessageBox::Ok);
165      exit(1);
166   }
167
168   // For now use the first disk we find
169   if ( ! autoGenPartitionLayout(sysDisks.at(0).at(1), true) )
170   {
171      QMessageBox::critical(this, tr("PC-BSD Installer"),
172        tr("Unable to suggest a partition for the detected disk."),
173        QMessageBox::Ok,
174        QMessageBox::Ok);
175   }
176
177   textEditDiskSummary->clear();
178   QStringList summary = getDiskSummary();
179   for ( int i=0; i < summary.count(); ++i)
180     textEditDiskSummary->append(summary.at(i));
181
182   textEditDiskSummary->moveCursor(QTextCursor::Start);
183
184}
185
186// Function which will auto-generate a partition layout based upon the target disk / slice
187bool Installer::autoGenPartitionLayout(QString target, bool isDisk)
188{
189  QString targetType, tmp;
190  int targetLoc, totalSize = 0, mntsize;
191  QString targetDisk, targetSlice, tmpPass, fsType;
192  bool ok;
193  ok = false;
194
195  // Clear out the original disk layout
196  sysFinalDiskLayout.clear();
197  QStringList fileSystem;
198  qDebug() << "Generating disk layout";
199
200
201  if ( isDisk ) {
202    targetType = "DRIVE";
203    targetSlice = "ALL";
204    targetDisk = target;
205    targetLoc = 1;
206  } else {
207    targetType = "SLICE";
208    targetDisk = target;
209    targetDisk.truncate(targetDisk.size() -2);
210    targetSlice = target;
211    targetSlice = targetSlice.remove(0, targetSlice.size() -2);
212    targetLoc = 2;
213  }
214 
215  // Lets get the size for this disk / partition
216  for (int i=0; i < sysDisks.count(); ++i) {
217      // Make sure to only add the slices to the listDiskSlices
218      if ( sysDisks.at(i).at(0) == targetType && target == sysDisks.at(i).at(targetLoc))
219        totalSize = sysDisks.at(i).at(targetLoc + 1).toInt(&ok);
220  }
221
222  // Give us a small buffer for rounding errors
223  totalSize = totalSize - 10;
224
225  // We got a valid size for this disk / slice, lets generate the layout now
226  if( !ok )
227    return false;
228
229
230  // If on amd64 lets use ZFS, it rox
231  if ( Arch == "amd64" ) {
232    // Add the main zfs pool with standard partitions
233    fsType= "ZFS";
[d63d157]234    fileSystem << targetDisk << targetSlice << "/,/tmp(compress=lzjb),/usr(canmount=off),/usr/home,/usr/jails,/usr/obj(compress=lzjb),/usr/pbi,/usr/ports(compress=gzip),/usr/ports/distfiles(compress=off),/usr/src(compress=gzip),/var(canmount=off),/var/audit(compress=lzjb),/var/log(compress=gzip),/var/tmp(compress=lzjb)" << fsType << tmp.setNum(totalSize) << "" << "";
[1620346]235    //qDebug() << "Auto-Gen FS:" <<  fileSystem;
236    sysFinalDiskLayout << fileSystem;
237    fileSystem.clear();
238    return true;
239  }
240
241  // Looks like not on amd64, fallback to UFS+SUJ and print a nice
242  // warning for the user explaining they *really* want to be on amd64
243  QMessageBox::warning(this, tr("PC-BSD Installer"),
244      tr("Detected that you are running the 32bit version. If your system is 64bit capable (most systems made after 2005), you really should be running the 64bit version"),
245      QMessageBox::Ok,
246      QMessageBox::Ok);
247
248  // Start the UFS layout now
249  mntsize = 2000;
250  fsType="UFS+SUJ";
251
252  fileSystem << targetDisk << targetSlice << "/" << fsType << tmp.setNum(mntsize) << "" << "";
253  totalSize = totalSize - mntsize;
254  //qDebug() << "Auto-Gen FS:" <<  fileSystem;
255  sysFinalDiskLayout << fileSystem;
256  fileSystem.clear();
257   
258
259  // Figure out the swap size, try for 2xPhysMem first, fallback to 256 if not enough space
260  mntsize = systemMemory * 2;
261  if ( totalSize - mntsize < 3000 )
262     mntsize = 256;
263
264  // Cap the swap size to 2GB
265  if ( mntsize > 2000 )
266     mntsize = 2000;
267
268  fileSystem << targetDisk << targetSlice << "SWAP" << "SWAP" << tmp.setNum(mntsize) << "" << "";
269  totalSize = totalSize - mntsize;
270  //qDebug() << "Auto-Gen FS:" <<  fileSystem;
271  sysFinalDiskLayout << fileSystem;
272  fileSystem.clear();
273
274  // If less than 3GB, skip /var and leave on /
275  if ( totalSize > 3000 ) {
276    // Figure out the default size for /var if we are on FreeBSD / PC-BSD
277    mntsize = 2048;
278    fileSystem << targetDisk << targetSlice << "/var" << fsType << tmp.setNum(mntsize) << "" << "";
279    totalSize = totalSize - mntsize;
280    //qDebug() << "Auto-Gen FS:" <<  fileSystem;
281    sysFinalDiskLayout << fileSystem;
282    fileSystem.clear();
283  }
284
285  // Now use the rest of the disk / slice for /usr
286  fileSystem << targetDisk << targetSlice << "/usr" << fsType << tmp.setNum(totalSize) << "" << "";
287  //qDebug() << "Auto-Gen FS:" <<  fileSystem;
288  sysFinalDiskLayout << fileSystem;
289  fileSystem.clear();
290
291  return true; 
292 
293}
294
295// Function which returns the pc-sysinstall cfg data
296QStringList Installer::getDiskSummary()
297{
298  QList<QStringList> copyList;
299  QStringList summaryList;
300  QString tmp, workingDisk, workingSlice, tmpSlice, XtraTmp, startPart, sliceSize;
301  int disk = 0;
302
303  // Copy over the list to a new variable we can mangle without modifying the original
304  copyList = sysFinalDiskLayout;
305
306  if ( copyList.at(0).at(0) == "MANUAL" )
307  {
308    summaryList << "";
309    summaryList << tr("Installing to file-system mounted at /mnt");
310    return summaryList;
311  }
312
313  // Start our summary
314  summaryList << "";
315  summaryList << "<b>" + tr("The disk will be setup with the following configuration:") + "</b>";
316
317  while ( ! copyList.empty() )
318  {
319    workingDisk = copyList.at(0).at(0);
320    workingSlice = copyList.at(0).at(1);
321    tmpSlice = workingSlice;
322
323    // Check if this is an install to "Unused Space"
324    for (int z=0; z < sysDisks.count(); ++z)
325      if ( sysDisks.at(z).at(0) == "SLICE" \
326        && sysDisks.at(z).at(2) == workingDisk + workingSlice \
327        && sysDisks.at(z).at(4) == "Unused Space" )
328          tmpSlice = "free";
329
330    // Check for any mirror for this device
331    for (int i=0; i < copyList.count(); ++i) {
332       if ( copyList.at(i).at(2).indexOf("MIRROR(" + workingDisk + ")") != -1 )
333       {
334         summaryList << tr("Disk:") + copyList.at(i).at(0) + " " + tr("Mirroring:") + workingDisk;
335         copyList.removeAt(i);
336         break;
337       }
338    }
339
340    // If after doing the mirror, our list is empty, break out
341    if ( copyList.empty() )
342      break;
343   
344    // If there is a dedicated /boot partition, need to list that first, see what is found
345    for (int i=0; i < copyList.count(); ++i) {
346      QStringList mounts = copyList.at(i).at(2).split(",");
347      for (int z = 0; z < mounts.size(); ++z) {
348        if ( copyList.at(i).at(0) == workingDisk \
349          && copyList.at(i).at(1) == workingSlice \
350          && mounts.at(z) == "/boot" )
351                startPart="/boot";
352      }
353    }
354
355    // If no dedicated /boot partition, then lets list "/" first
356    if(startPart.isEmpty())
357        startPart="/";
358
359    // Start by looking for the root partition
360    for (int i=0; i < copyList.count(); ++i) {
361      QStringList mounts = copyList.at(i).at(2).split(",");
362      for (int z = 0; z < mounts.size(); ++z) {
363        if ( copyList.at(i).at(0) == workingDisk \
364          && copyList.at(i).at(1) == workingSlice \
365          && mounts.at(z) == startPart ) {
366
367          // Check if we have any extra arguments to throw on the end
368          XtraTmp="";
369          if ( ! copyList.at(i).at(5).isEmpty() )
370            XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
371
372          // Write the user summary
373          summaryList << "";
374          summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
375          summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
376          summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
377          if ( copyList.at(i).at(3) == "ZFS" ) {
378            QStringList zDS = copyList.at(i).at(2).split(",/");
379            QString zTMP;
380            for (int ds = 0; ds < zDS.size(); ++ds) {
381              if ( zDS.at(ds) != "/" )
382                zDS.replace(ds, "/" + zDS.at(ds));
383              if ( zDS.at(ds).indexOf("(") != -1 ) {
384                zTMP = zDS.at(ds);
385                zTMP.replace("(", " (");
386                zDS.replace(ds, zTMP );
387              }
388            } 
389            summaryList << tr("ZFS Datasets:<br>") + " " + zDS.join("<br>");
390          } else {
391            summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
392          }
393          if ( ! XtraTmp.isEmpty() ) {
394            summaryList << tr("Options:") + " " + copyList.at(i).at(5);
395          }
396
397          // Done with this item, remove it now
398          copyList.removeAt(i);
399          break;
400        }
401      }
402    }
403
404
405    // Now look for SWAP
406    for (int i=0; i < copyList.count(); ++i) {
407      if ( copyList.at(i).at(0) == workingDisk \
408        && copyList.at(i).at(1) == workingSlice \
409        && copyList.at(i).at(2) == "SWAP" ) {
410
411        // Write the user summary
412        summaryList << "";
413        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
414        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
415        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
416
417        // Done with this item, remove it now
418        copyList.removeAt(i);
419        break;
420      }
421    }
422
423 
424    // Now look for any other partitions
425    int count = copyList.count();
426    for (int i=0; i < count; ++i) {
427      if ( copyList.at(i).at(0) == workingDisk \
428        && copyList.at(i).at(1) == workingSlice ) {
429
430        // Check if we have any extra arguments to throw on the end
431        XtraTmp="";
432        if ( ! copyList.at(i).at(5).isEmpty() )
433          XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
434
435        // If we are working on the last partition, set the size to 0 to use remaining disk
436        if ( i == (count - 1) ) 
437                sliceSize = "0";
438        else
439                sliceSize=copyList.at(i).at(4);
440
441        // Write the user summary
442        summaryList << "";
443        summaryList << tr("Partition:") + " " + workingDisk + "(" + workingSlice + "):";
444        summaryList << tr("FileSystem:") + " " + copyList.at(i).at(3);
445        summaryList << tr("Size:") + " " + copyList.at(i).at(4) + "MB ";
446        if ( copyList.at(i).at(3) != "ZFS" )
447          summaryList << tr("Mount:") + " " + copyList.at(i).at(2);
448        if ( ! XtraTmp.isEmpty() ) {
449          summaryList << tr("Options:") + " " + copyList.at(i).at(5);
450        }
451
452        // Done with this item, remove it now
453        copyList.removeAt(i);
454        i--;
455        count--;
456      }
457    }
458
459    // Increment our disk counter
460    disk++;
461  }
462
463  return summaryList;
464}
465
466void Installer::slotDiskCustomizeClicked()
467{
468  wDisk = new wizardDisk();
469  wDisk->programInit();
470  wDisk->setWindowModality(Qt::ApplicationModal);
471  connect(wDisk, SIGNAL(saved(QList<QStringList>, bool, bool)), this, SLOT(slotSaveDiskChanges(QList<QStringList>, bool, bool)));
472  wDisk->show();
473  wDisk->raise();
474}
475
476void Installer::slotDesktopCustomizeClicked()
477{
478  desks = new desktopSelection();
479  if ( wheelCurItem != wPCSERVER && wheelCurItem != 11 && wheelCurItem != 12)
480     desks->programInit(listDeskPkgs,selectedPkgs);
481  else
482     desks->programInit(listServerPkgs,selectedPkgs);
483  desks->setWindowModality(Qt::ApplicationModal);
484  connect(desks, SIGNAL(saved(QStringList)), this, SLOT(slotSaveMetaChanges(QStringList)));
485  desks->show();
486  desks->raise();
487}
488
489void Installer::slotSaveMetaChanges(QStringList sPkgs)
490{
491  selectedPkgs = sPkgs;
492
493  // Only add +10 if we are not already on the custom screen
494  if ( wheelCurItem < 10 )
495    wheelCurItem= wheelCurItem + 10;
496
497  switch (wheelCurItem) {
498    case 12:
499        groupDeskSummary->setTitle(tr("TrueOS Package Selection"));
500        break;
501    case 11:
502        groupDeskSummary->setTitle(tr("FreeBSD Package Selection"));
503        break;
504    default:
505        groupDeskSummary->setTitle(tr("PC-BSD Package Selection"));
506        break;
507  }
508
509  textDeskSummary->setText(tr("The following meta-pkgs will be installed:") + "<br>" + selectedPkgs.join("<br>"));
510  graphicsViewOS->setScene(customScene);
511}
512
513void Installer::slotSaveDiskChanges(QList<QStringList> newSysDisks, bool MBR, bool GPT)
514{
515  // Save the new disk layout
516  loadMBR = MBR;
517  loadGPT = GPT;
518  sysFinalDiskLayout = newSysDisks;
519  textEditDiskSummary->clear();
520  QStringList summary = getDiskSummary();
521  for ( int i=0; i < summary.count(); ++i)
522    textEditDiskSummary->append(summary.at(i));
523               
524  textEditDiskSummary->moveCursor(QTextCursor::Start);
525 
526  // Regenerate the config
527  startConfigGen();
528}
529
530void Installer::slotDesktopLeftClicked()
531{
532  if ( wheelCurItem >= 10 ) {
533    int ret = QMessageBox::question(this, tr("PC-BSD Installer"),
534                              tr("You currently have a custom package set configured. Continue changing to a default set?"),
535                              QMessageBox::No | QMessageBox::Yes,
536                              QMessageBox::No);
537    switch (ret) {
538    case QMessageBox::Yes:
539        break;
540    case QMessageBox::No: // :)
541        return;
542        break;
543    }
544    wheelCurItem = wheelCurItem - 10;
545    graphicsViewOS->setScene(defaultScene);
546  }
547  moveDesktopWheel(false);
548}
549
550void Installer::slotDesktopRightClicked()
551{
552  if ( wheelCurItem >= 10 ) {
553    int ret = QMessageBox::question(this, tr("PC-BSD Installer"),
554                              tr("You currently have a custom package set configured. Continue changing to a default set?"),
555                              QMessageBox::No | QMessageBox::Yes,
556                              QMessageBox::No);
557    switch (ret) {
558    case QMessageBox::Yes:
559        break;
560    case QMessageBox::No: // :)
561        return;
562        break;
563    }
564    wheelCurItem = wheelCurItem - 10;
565    graphicsViewOS->setScene(defaultScene);
566  }
567  moveDesktopWheel(true);
568}
569
570void Installer::moveDesktopWheel(bool direction)
571{
572  qDebug() << wheelCurItem << direction;
573  // Make sure we aren't scrolling too far
574  if ( direction && wheelCurItem >= wheelIcons.size() )
575    return;
576  if ( ! direction && wheelCurItem <= 1 )
577    return;
578
579
580  int tItem, tPixel, cPixel;
581  cPixel=96 + ((wheelCurItem-1) * 64) + (wheelCurItem * 32);
582
583  // Right
584  if ( direction ) {
585    tItem=wheelCurItem + 1;
586    tPixel=96 + ((tItem-1) * 64) + (tItem * 32);
587  } else {
588  // Left
589    tItem=wheelCurItem - 1;
590    tPixel=96 + ((tItem-1) * 64) + (tItem * 32);
591  } 
592
593  if ( direction ) {
594    while ( cPixel < tPixel ) {
595      cPixel++;
596      graphicsViewOS->centerOn(cPixel,0);
597      graphicsViewOS->show();
598      QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 22);
599     
600    }
601  } else {
602    while ( cPixel > tPixel ) {
603      cPixel--;
604      graphicsViewOS->centerOn(cPixel,0);
605      graphicsViewOS->show();
606      QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 22);
607    }
608  }
609 
610  wheelCurItem=tItem;
611
612  groupDeskSummary->setTitle(wheelName.at(tItem-1));
613  textDeskSummary->setText(wheelDesc.at(tItem-1));
614
615  // No custom packages for FreeBSD vanilla
616  if ( wheelCurItem == 1 ) 
617    pushDeskCustomize->setEnabled(false);
618  else
619    pushDeskCustomize->setEnabled(true);
620 
621  changeMetaPkgSelection();
622}
623
624void Installer::changeMetaPkgSelection()
625{
626
627  // Set the default desktop meta-pkgs based upon the selection
628  // 1 = FreeBSD
629  switch (wheelCurItem)
630  {
631    case wKDE:
632      selectedPkgs.clear();
633      selectedPkgs << "KDE" << "KDE-Accessibility" << "KDE-Artwork" << "KDE-Education" << "KDE-Games" << "KDE-Graphics" << "KDE-Multimedia" << "KDE-Network" << "KDE-PIM";
634      if ( comboLanguage->currentIndex() != 0 ) 
635         selectedPkgs << "KDE-L10N";
636      break;
637    case wLXDE:
638      selectedPkgs.clear();
639      selectedPkgs << "LXDE";
640      break;
641    case wGNOME:
642      selectedPkgs.clear();
643      selectedPkgs << "GNOME" << "GNOME-Accessibility" << "GNOME-Games" << "GNOME-Net" << "GNOME-Utilities";
644      break;
645    case wXFCE:
646      selectedPkgs.clear();
647      selectedPkgs << "XFCE" << "XFCE-Plugins";
648      break;
649    default:
650      selectedPkgs.clear();
651      return;
652  }
653
654  // Check if we are using NVIDIA driver and include it automatically
655  QFile file("/etc/X11/xorg.conf");
656  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
657      return;
658         
659  QTextStream in(&file);
660  while (!in.atEnd()) {
661      QString line = in.readLine();
662      if ( line.indexOf("nvidia") != -1 ) {
663        selectedPkgs << "NVIDIA";
664        break;
665      }
666  }     
667  file.close();
668  // Done with NVIDIA check
669
670  qDebug() << selectedPkgs;
671
672}
673
674void Installer::initDesktopSelector()
675{
676    // Init the desktop selector
677    wheelIcons << ":modules/images/freebsd.png" << ":/modules/images/pcbsd-server.png" << ":/PCBSD/images/kde.png" << ":/PCBSD/images/lxde.png" << ":/PCBSD/images/gnome.png" << ":/PCBSD/images/xfce.png";
678    wheelName << "FreeBSD Server" << "TrueOS" << "KDE" << "LXDE" << "GNOME" << "XFCE"; 
679    wheelDesc << tr("FreeBSD is an advanced operating system for modern server, desktop, and embedded computer platforms. FreeBSD's code base has undergone over thirty years of continuous development, improvement, and optimization.") \
680    << tr("TrueOS is a console based server running FreeBSD. It includes command-line versions of The Warden jail management, PBI manager, ZFS boot environments (beadm), and other helpful utilities for system administrators.")  \
681    << tr("KDE is a full-featured desktop environment, which includes support for 3D desktop effects, multiple desktops, and a variety of built-in tools and utilities for both new and power-desktop users.<br><br>* Recommended for higher-end systems with 2GB of RAM or more *") \
682    << tr("LXDE is a lightweight desktop, minimalist in nature, with support for multiple-desktops, a system tray, application menu and more.<br><br>* Recommended for netbooks, or lower-end systems * ") \
683    << tr("GNOME is a full-featured desktop environment, complete with a large number of integrated utilities and tools for desktop users.") \
684    << tr("XFCE is a light and modular desktop, with a number of features to enhance customizing the desktop to your liking."); 
685
686    int xOff=96;
687    defaultScene = new QGraphicsScene(0,0,(96 + 96 + (wheelIcons.size()*64) + (wheelIcons.size()*32) ),64);
688    for ( int i = 0; i < wheelIcons.size(); ++i) {
689      defaultScene->addPixmap(QPixmap(wheelIcons.at(i)))->setOffset(xOff,0);
690      xOff = xOff +96;
691    }
692    graphicsViewOS->setScene(defaultScene);
693
694    // If less than 2GB memory, default to LXDE, otherwise KDE
695    if ( systemMemory > 2048 )  {
696      wheelCurItem=2;
697    } else {
698      wheelCurItem=3;
699    }
700    graphicsViewOS->centerOn(191,0);
701    graphicsViewOS->show();
702    moveDesktopWheel(true);
703
704    customScene = new QGraphicsScene(0,0,220,64);
705    customScene->addText(tr("Custom Package Selection"));
706
707    // Connect our slots
708    connect(pushDeskRight,SIGNAL(clicked()), this, SLOT(slotDesktopRightClicked()));
709    connect(pushDeskLeft,SIGNAL(clicked()), this, SLOT(slotDesktopLeftClicked()));
710    connect(pushDeskCustomize,SIGNAL(clicked()), this, SLOT(slotDesktopCustomizeClicked()));
711}
712
713void Installer::proceed(bool forward)
714{
715    int count = installStackWidget->count() - 1;
716    int index = installStackWidget->currentIndex();
717
718    index = forward ?
719            (index == count ? count : index + 1) :
720            (index == 0 ? 0 : index - 1);
721
722    if ( index > 0 && index != 4)
723      backButton->setVisible(true);
724    else
725      backButton->setVisible(false);
726
727    installStackWidget->setCurrentIndex(index);
728}
729
730// Slot which is called when the Finish button is clicked
731void Installer::slotFinished()
732{
733  qApp->quit();
734}
735
736void Installer::slotSaveFBSDSettings(QString rootPW, QString name, QString userName, QString userPW, QString shell, QString hostname, bool ssh, bool src, bool ports, QStringList netSettings)
737{
738  fRootPW = rootPW;
739  fName = name;
740  fUserName = userName;
741  fUserPW = userPW;
742  fShell = shell;
743  fHost = hostname;
744  fSSH = ssh;
745  fSRC = src;
746  fPORTS = ports;
747  fNetSettings = netSettings;
748  installStackWidget->setCurrentIndex(installStackWidget->currentIndex() + 1);
749
750  // Generate the pc-sysinstall config
751  startConfigGen();
752}
753
754void Installer::slotNext()
755{
756   QString tmp;
757
758   // If no pkgs on media
759   if ( installStackWidget->currentIndex() == 0 && ! hasPkgsOnMedia) {
760     installStackWidget->setCurrentIndex(2);
761     return;
762   }
763
764   // Start the FreeBSD wizard
765   if ( installStackWidget->currentIndex() == 1 && (wheelCurItem == wFREEBSD || wheelCurItem == wPCSERVER || wheelCurItem == 12) ) {
766     bool tOS;
767     if ( wheelCurItem == wPCSERVER || wheelCurItem == 12 )
768       tOS = true;
769     else
770       tOS = false;
771
772     wFBSD = new wizardFreeBSD();
773     wFBSD->setWindowModality(Qt::ApplicationModal);
774     wFBSD->programInit(tOS);
775     connect(wFBSD, SIGNAL(saved(QString, QString, QString, QString, QString, QString, bool, bool, bool, QStringList)), this, SLOT(slotSaveFBSDSettings(QString, QString, QString, QString, QString, QString, bool, bool, bool, QStringList)));
776     wFBSD->show();
777     wFBSD->raise();
778     return ;
779   }
780
781   // Create the pc-sysinstall config
782   if ( installStackWidget->currentIndex() == 1 )
783     startConfigGen();
784
785   // If the chosen disk is too small or partition is invalid, don't continue
786   if ( installStackWidget->currentIndex() == 2 && ! checkDiskRequirements())
787      return;
788
789   if ( installStackWidget->currentIndex() == 2 )
790   {
791      startConfigGen();
792      int ret = QMessageBox::question(this, tr("PC-BSD Installer"),
793                                tr("Start the installation now?"),
794                                QMessageBox::No | QMessageBox::Yes,
795                                QMessageBox::No);
796      switch (ret) {
797      case QMessageBox::Yes:
798          startInstall();
799          break;
800      case QMessageBox::No: // :)
801          return;
802          break;
803      }
804   }
805
806   proceed(true);
807}
808
809void Installer::slotBack()
810{
811   // If no pkgs on media
812   if ( installStackWidget->currentIndex() == 2 && ! hasPkgsOnMedia) {
813        installStackWidget->setCurrentIndex(0);
814        return;
815   }
816
817   proceed(false);
818}
819
820void Installer::slotAbort()
821{
822   close();
823}
824
825void Installer::slotChangeLanguage()
826{
827    if ( comboLanguage->currentIndex() == -1 )
828      return;
829
830    // Figure out the language code
831    QString langCode = languages.at(comboLanguage->currentIndex());
832   
833    // Grab the language code
834    langCode.truncate(langCode.lastIndexOf(")"));
835    langCode.remove(0, langCode.lastIndexOf("(") + 1); 
836
837    // Check what directory our app is in
838    QString appDir;
839    if ( QFile::exists("/usr/local/bin/pc-sysinstaller") )
840      appDir = "/usr/local/share/pcbsd";
841    else
842      appDir = QCoreApplication::applicationDirPath();
843
844    //QTranslator *translator = new QTranslator();
845    qDebug() << "Remove the translator";
846    if ( ! translator->isEmpty() )
847      QCoreApplication::removeTranslator(translator);
848
849    if (translator->load( QString("SysInstaller_") + langCode, appDir + "/i18n/" )) {
850      qDebug() << "Load new Translator" << langCode;
851      QCoreApplication::installTranslator(translator);
852      this->retranslateUi(this);
853    }
854}
855
856void Installer::changeLang(QString code)
857{
858   // Change the language in the combobox with the current running one
859   comboLanguage->disconnect();
860
861   for (int i=0; i < languages.count(); ++i) {
862      if ( languages.at(i).indexOf("(" + code + ")" ) != -1 ) {
863        comboLanguage->setCurrentIndex(i); 
864      }
865   }
866
867   connect(comboLanguage, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotChangeLanguage()));
868}
869
870QStringList Installer::getGlobalCfgSettings()
871{
872
873  QStringList tmpList;
874  QString tmp, upDrive;
875
876  tmpList << "# Auto-Generated pc-sysinstall configuration";
877  tmpList << "installInteractive=no";
878
879  if ( sysFinalDiskLayout.at(0).at(0) == "MANUAL" )
880  {
881    tmpList << "installMode=extract";
882    tmpList << "installLocation=/mnt";
883  } else {
884    // Doing a fresh install
885    tmpList << "installMode=fresh";
886  }
887 
888  QString distFiles;
889  distFiles="base doc games kernel";
890  if ( Arch == "amd64" )
891     distFiles+=" lib32";
892
893  // If we are doing a PC-BSD install
894  if ( wheelCurItem != wPCSERVER && wheelCurItem != 12 && wheelCurItem != wFREEBSD ) {
895    tmpList << "installType=PCBSD";
896    tmpList << "packageType=dist";
897  } else {
898    tmpList << "installType=FreeBSD";
899    tmpList << "packageType=dist";
900  }
901
902  // Set the distFiles being used
903  tmpList << "distFiles=" + distFiles;
904  tmpList << "";
905
906  // If we have a custom hostname, add it to the config
907  if ( ! fHost.isEmpty() )
908    tmpList << "hostname=" + fHost;
909
910 
911  // Networking setup
912  if ( wheelCurItem != wFREEBSD && wheelCurItem != wPCSERVER && wheelCurItem != 12 ) {
913    // PC-BSD network setup
914    tmpList << "netSaveDev=AUTO-DHCP-SLAAC";
915  } else {
916    // FreeBSD network setup
917    if ( fNetSettings.at(0) == "AUTO-DHCP" )
918      tmpList << "netSaveDev=AUTO-DHCP";
919    else if ( fNetSettings.at(0) == "AUTO-DHCP-SLAAC" ) {
920      tmpList << "netSaveDev=AUTO-DHCP-SLAAC";
921      // We cannot rely on SLAAC to provide DNS for example.  The same is true
922      // for DHCP but the worls seems to have forgotten...
923      tmpList << "netSaveIPv6=" + fNetSettings.at(5);
924      tmpList << "netSaveIPv6NameServer=" + fNetSettings.at(6);
925      tmpList << "netSaveIPv6DefaultRouter=" + fNetSettings.at(7);
926    } else if ( fNetSettings.at(0) == "IPv6-SLAAC" ) {
927       tmpList << "netSaveDev=IPv6-SLAAC";
928      // We cannot rely on SLAAC to provide DNS for example.  The same is true
929      // for DHCP but the worls seems to have forgotten...
930      tmpList << "netSaveIPv6=" + fNetSettings.at(5);
931      tmpList << "netSaveIPv6NameServer=" + fNetSettings.at(6);
932      tmpList << "netSaveIPv6DefaultRouter=" + fNetSettings.at(7);
933    } 
934    else
935    {
936      tmp = fNetSettings.at(0);
937      if ( tmp.indexOf(":") > 0 )
938        tmp.truncate(tmp.indexOf(":"));
939      tmpList << "netSaveDev=" + tmp;
940      tmpList << "netSaveIP_" + tmp + "=" + fNetSettings.at(1); 
941      tmpList << "netSaveMask_" + tmp + "=" + fNetSettings.at(2);
942      tmpList << "netSaveNameServer=" + fNetSettings.at(3);
943      tmpList << "netSaveDefaultRouter=" + fNetSettings.at(4);
944      tmpList << "netSaveIPv6=" + fNetSettings.at(5);
945      tmpList << "netSaveIPv6NameServer=" + fNetSettings.at(6);
946      tmpList << "netSaveIPv6DefaultRouter=" + fNetSettings.at(7);
947    }
948  }
949
950
951  // Doing install from /dist directory
952  tmpList << "installMedium=local"; 
953  tmpList << "localPath=/dist";
954
955  if ( comboLanguage->currentIndex() != 0 ) {
956    QString lang = languages.at(comboLanguage->currentIndex());
957    // Grab the language code
958    lang.truncate(lang.lastIndexOf(")"));
959    lang.remove(0, lang.lastIndexOf("(") + 1);
960    tmpList << "";
961    tmpList << "localizeLang=" + lang;
962  }
963
964  // Setup custom keyboard layouts
965  /* KPM
966  tmpList << "";
967  tmpList << "# Keyboard Layout Options";
968  tmp = comboBoxKeyboardModel->currentText();
969  tmp.truncate(tmp.indexOf(")"));
970  tmp = tmp.remove(0, tmp.indexOf(" (") + 2 );
971  tmpList << "localizeKeyModel=" + tmp;
972
973  tmp = listKbLayouts->currentItem()->text();
974  tmp.truncate(tmp.indexOf(")"));
975  tmp = tmp.remove(0, tmp.indexOf(" (") + 2 );
976  tmpList << "localizeKeyLayout=" + tmp;
977
978  tmp = listKbVariants->currentItem()->text();
979  if ( tmp != "<none>" ) {
980    tmp.truncate(tmp.indexOf(")"));
981    tmp = tmp.remove(0, tmp.indexOf(" (") + 2 );
982    tmpList << "localizeKeyVariant=" + tmp;
983  }
984  */
985
986  tmpList << " ";
987
988  return tmpList;
989}
990
991void Installer::startConfigGen()
992{
993
994  if ( ! haveWarnedSpace )
995     checkSpaceWarning();
996
997  QStringList cfgList;
998
999  // Generate the config file now
1000  cfgList+=getGlobalCfgSettings();
1001
1002  cfgList+=getDiskCfgSettings();
1003
1004  cfgList+=getComponentCfgSettings();
1005
1006  // Save the install config script to disk
1007  cfgList << "runExtCommand=/root/save-config.sh";
1008
1009  cfgList+= "";
1010
1011  // If doing install from package disk
1012  if ( hasPkgsOnMedia )
1013    cfgList+=getDeskPkgCfg();
1014
1015  cfgList+= "";
1016
1017  if ( wheelCurItem != wFREEBSD && wheelCurItem != wPCSERVER && wheelCurItem != 12 ) {
1018    // Doing PC-BSD Install
1019
1020    QString lang;
1021    if ( comboLanguage->currentIndex() != 0 )
1022      lang = languages.at(comboLanguage->currentIndex());
1023    else
1024      lang="en_US";
1025
1026    // Setup the desktop
1027    cfgList << "runCommand=sh /usr/local/share/pcbsd/scripts/sys-init.sh desktop " + lang;
1028
1029    // Setup for a fresh system first boot
1030    cfgList << "# Touch flags to enable PC-BSD setup at first boot";
1031    cfgList << "runCommand=touch /var/.runxsetup";
1032    cfgList << "runCommand=touch /var/.pcbsd-firstboot";
1033    cfgList << "runCommand=touch /var/.pcbsd-firstgui";
1034
1035  } else if ( wheelCurItem == wPCSERVER || wheelCurItem == 12 ) {
1036    // Doing TrueOS Install
1037    cfgList+=getUsersCfgSettings();
1038
1039    // Enable SSH?
1040    if ( fSSH )
1041      cfgList << "runCommand=echo 'sshd_enable=\"YES\"' >>/etc/rc.conf";
1042
1043    // Setup the TrueOS server
1044    cfgList << "runCommand=sh /usr/local/share/pcbsd/scripts/sys-init.sh server";
1045
1046  } else { // End of PC-BSD specific setup
1047    // Doing FreeBSD Install
1048    cfgList+=getUsersCfgSettings();
1049
1050    // Enable SSH?
1051    if ( fSSH )
1052      cfgList << "runCommand=echo 'sshd_enable=\"YES\"' >>/etc/rc.conf";
1053
1054  }
1055
1056  // Run newaliases to fix mail errors
1057  cfgList << "runCommand=newaliases";
1058
1059  // Now write out the cfgList to file
1060  QFile cfgfile( PCSYSINSTALLCFG );
1061  if ( cfgfile.open( QIODevice::WriteOnly ) ) {
1062    QTextStream stream( &cfgfile );
1063    for ( int i=0; i < cfgList.count(); ++i) {
1064      stream <<  cfgList.at(i) << "\n";
1065    }
1066    cfgfile.close();
1067  }
1068}
1069
1070void Installer::slotHelp()
1071{
1072        pcHelp = new dialogHelp();
1073        switch (installStackWidget->currentIndex()) {
1074        case 0:
1075                pcHelp->dialogInit(HELPTEXT0);
1076                break;
1077        case 1:
1078                pcHelp->dialogInit(HELPTEXT1);
1079                break;
1080        case 2:
1081                pcHelp->dialogInit(HELPTEXT2);
1082                break;
1083        case 3:
1084                pcHelp->dialogInit(HELPTEXT3);
1085                break;
1086        default:
1087                pcHelp->dialogInit("No help text...");
1088                break;
1089        }
1090        pcHelp->show();
1091}
1092
1093// Function which returns the pc-sysinstall cfg data
1094QStringList Installer::getDiskCfgSettings()
1095{
1096  QStringList tmpList;
1097  QList<QStringList> copyList;
1098  QString tmp, workingDisk, workingSlice, tmpSlice, XtraTmp, startPart, sliceSize;
1099  int disk = 0;
1100
1101  // Copy over the list to a new variable we can mangle without modifying the original
1102  copyList = sysFinalDiskLayout;
1103
1104  // Doing manual extraction
1105  if ( copyList.at(0).at(0) == "MANUAL" )
1106    return QStringList();
1107
1108  while ( ! copyList.empty() )
1109  {
1110    workingDisk = copyList.at(0).at(0);
1111    workingSlice = copyList.at(0).at(1);
1112    tmpSlice = workingSlice;
1113    tmpList << "# Disk Setup for " + workingDisk ;
1114
1115    // Check if this is an install to "Unused Space"
1116    for (int z=0; z < sysDisks.count(); ++z)
1117      if ( sysDisks.at(z).at(0) == "SLICE" \
1118        && sysDisks.at(z).at(2) == workingDisk + workingSlice \
1119        && sysDisks.at(z).at(4) == "Unused Space" )
1120          tmpSlice = "free";
1121
1122    tmpList << "disk" + tmp.setNum(disk) + "=" + workingDisk;
1123    tmpList << "partition=" + tmpSlice;
1124
1125    // Are we loading a boot-loader?
1126    if ( loadMBR )
1127      tmpList << "bootManager=bsd";
1128    else
1129      tmpList << "bootManager=none";
1130
1131    // Set the GPT/MBR options
1132    if ( loadGPT ) 
1133      tmpList << "partscheme=GPT";
1134    else
1135      tmpList << "partscheme=MBR";
1136
1137    tmpList << "commitDiskPart";
1138    tmpList << "";
1139
1140    // If after doing the mirror, our list is empty, break out
1141    if ( copyList.empty() )
1142      break;
1143   
1144    // Now print the partition section for this slice
1145    tmpList << "# Partition Setup for " + workingDisk + "(" + workingSlice + ")";
1146    tmpList << "# All sizes are expressed in MB";
1147    tmpList << "# Avail FS Types, UFS, UFS+S, UFS+SUJ, UFS+J, ZFS, SWAP";
1148    tmpList << "# UFS.eli, UFS+S.eli, UFS+SUJ, UFS+J.eli, ZFS.eli, SWAP.eli";
1149
1150    // If there is a dedicated /boot partition, need to list that first, see what is found
1151    for (int i=0; i < copyList.count(); ++i) {
1152      QStringList mounts = copyList.at(i).at(2).split(",");
1153      for (int z = 0; z < mounts.size(); ++z) {
1154        if ( copyList.at(i).at(0) == workingDisk \
1155          && copyList.at(i).at(1) == workingSlice \
1156          && mounts.at(z) == "/boot" )
1157                startPart="/boot";
1158      }
1159    }
1160
1161    // If no dedicated /boot partition, then lets list "/" first
1162    if(startPart.isEmpty())
1163        startPart="/";
1164
1165    // Start by looking for the root partition
1166    for (int i=0; i < copyList.count(); ++i) {
1167      QStringList mounts = copyList.at(i).at(2).split(",");
1168      for (int z = 0; z < mounts.size(); ++z) {
1169        if ( copyList.at(i).at(0) == workingDisk \
1170          && copyList.at(i).at(1) == workingSlice \
1171          && mounts.at(z) == startPart ) {
1172
1173          // Check if we have any extra arguments to throw on the end
1174          XtraTmp="";
1175          if ( ! copyList.at(i).at(5).isEmpty() )
1176            XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
1177
1178          // Write out the partition line
1179          tmpList << "disk" + tmp.setNum(disk) + "-part=" \
1180                   + copyList.at(i).at(3) + " " + copyList.at(i).at(4) \
1181                   + " " + copyList.at(i).at(2) + XtraTmp;
1182
1183          // Check if we have an encryption passphrase to use
1184          if ( ! copyList.at(i).at(6).isEmpty() )
1185            tmpList << "encpass=" + copyList.at(i).at(6);
1186
1187          // Done with this item, remove it now
1188          copyList.removeAt(i);
1189          break;
1190        }
1191      }
1192    }
1193
1194    // Now look for SWAP
1195    for (int i=0; i < copyList.count(); ++i) {
1196      if ( copyList.at(i).at(0) == workingDisk \
1197        && copyList.at(i).at(1) == workingSlice \
1198        && copyList.at(i).at(2) == "SWAP" ) {
1199
1200        // Write the partition line
1201        tmpList << "disk" + tmp.setNum(disk) + "-part=" \
1202                 + copyList.at(i).at(3) + " " + copyList.at(i).at(4) \
1203                 + " none";
1204
1205        // Done with this item, remove it now
1206        copyList.removeAt(i);
1207        break;
1208      }
1209    }
1210 
1211    // Now look for any other partitions
1212    int count = copyList.count();
1213    for (int i=0; i < count; ++i) {
1214      if ( copyList.at(i).at(0) == workingDisk \
1215        && copyList.at(i).at(1) == workingSlice ) {
1216
1217        // Check if we have any extra arguments to throw on the end
1218        XtraTmp="";
1219        if ( ! copyList.at(i).at(5).isEmpty() )
1220          XtraTmp=" (" + copyList.at(i).at(5) + ")" ;
1221
1222        // If we are working on the last partition, set the size to 0 to use remaining disk
1223        if ( i == (count - 1) ) 
1224                sliceSize = "0";
1225        else
1226                sliceSize=copyList.at(i).at(4);
1227
1228        // Write the partition line
1229        tmpList << "disk" + tmp.setNum(disk) + "-part=" \
1230                 + copyList.at(i).at(3) + " " + sliceSize \
1231                 + " " + copyList.at(i).at(2) + XtraTmp;
1232
1233        // Check if we have an encryption passphrase to use
1234        if ( ! copyList.at(i).at(6).isEmpty() )
1235          tmpList << "encpass=" + copyList.at(i).at(6);
1236
1237        // Done with this item, remove it now
1238        copyList.removeAt(i);
1239        i--;
1240        count--;
1241      }
1242    }
1243
1244
1245    // Close out this partition section
1246    tmpList << "commitDiskLabel";
1247    tmpList << "";
1248
1249    // Increment our disk counter
1250    disk++;
1251  }
1252
1253  return tmpList;
1254}
1255
1256// Slot which checks any disk requirements before procceding to the next page
1257bool Installer::checkDiskRequirements()
1258{
1259  // For now just return true, the wizard should handle making sure
1260  // the user doesn't shoot themselves in the foot during disk setup
1261  return true;
1262}
1263
1264// Function which begins the backend install, and connects slots to monitor it
1265void Installer::startInstall()
1266{
1267  // Disable the back / next buttons until we are finished
1268  nextButton->setEnabled(false);
1269  backButton->setEnabled(false);
1270  progressBarInstall->setValue(0); 
1271  installFoundCounter = false;
1272  installFoundMetaCounter = false;
1273  installFoundFetchOutput = false;
1274
1275  // Setup some defaults for the secondary progress bar
1276  progressBarInstall2->setValue(0); 
1277  progressBarInstall2->setHidden(true); 
1278  labelInstallStatus2->setText("");
1279  labelInstallStatus2->setHidden(true);
1280
1281  // Kill any hald instances, which causes failures to install when it
1282  // tries to mount our new partitions
1283  QProcess::execute("killall", QStringList() << "hald");
1284
1285  // Start our process to begin the install
[027bbae]1286  QString PCSYSINSTALL;
1287  if ( QFile::exists("/root/pc-sysinstall/pc-sysinstall") ) 
1288     PCSYSINSTALL = "/root/pc-sysinstall/pc-sysinstall";
1289  else 
1290     PCSYSINSTALL = "/usr/local/sbin/pc-sysinstall";
1291
[1620346]1292  QString program = PCSYSINSTALL;
1293  QStringList arguments;
1294  arguments << "-c" << PCSYSINSTALLCFG;
1295
1296  installProc = new QProcess();
1297  installProc->setProcessChannelMode(QProcess::MergedChannels);
1298  connect(installProc,SIGNAL(finished( int, QProcess::ExitStatus)),this,SLOT(slotInstallProcFinished( int, QProcess::ExitStatus)));
1299  connect(installProc,SIGNAL(readyRead()),this,SLOT(slotReadInstallerOutput()));
1300  installProc->start(program, arguments);
1301
1302}
1303
1304// Function run when the install failed to prompt user for course of action
1305void Installer::installFailed()
1306{
1307   QString sysLog;
1308   labelInstallStatus->setText(tr("Failed!"));
1309
1310   QMessageBox msgBox;
1311   msgBox.setWindowTitle(tr("PC-BSD Installer"));
1312   msgBox.setIcon(QMessageBox::Critical);
1313   msgBox.setText(tr("The installer has encountered an error and has been halted."));
1314   msgBox.setInformativeText(tr("Do you want to generate an error report?"));
1315   msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1316   msgBox.setDefaultButton(QMessageBox::Yes);
1317
1318   // If we have a log, show it in the detailed view button
1319   if ( QFile::exists("/tmp/.pc-sysinstall/pc-sysinstall.log") )
1320   {
1321     QFile logFile("/tmp/.pc-sysinstall/pc-sysinstall.log");
1322     if (logFile.open(QIODevice::ReadOnly | QIODevice::Text))
1323         while (!logFile.atEnd())
1324           sysLog = sysLog + logFile.readLine() + "\n";
1325     msgBox.setDetailedText(sysLog);
1326   }
1327   int ret = msgBox.exec();
1328
1329   switch (ret) {
1330   case QMessageBox::Yes:
1331       // Generate the error report
1332       Scripts::Backend::createErrorReport();
1333       break;
1334   case QMessageBox::No: // :)
1335       break;
1336   }
1337
1338   QMessageBox msgBox2;
1339   msgBox2.setWindowTitle(tr("PC-BSD Installer"));
1340   msgBox2.setIcon(QMessageBox::Critical);
1341   msgBox2.setText(tr("Restart the system now?") );
1342   msgBox2.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1343   msgBox2.setDefaultButton(QMessageBox::Yes);
1344   msgBox2.setDetailedText(sysLog);
1345
1346   ret = msgBox2.exec();
1347
1348   switch (ret) {
1349   case QMessageBox::Yes:
1350       close();
1351       break;
1352   case QMessageBox::No: // :)
1353       break;
1354   }
1355
1356}
1357
1358// Slot which is called when the installation has finished
1359void Installer::slotInstallProcFinished( int exitCode, QProcess::ExitStatus status)
1360{
1361  QString tmp;
1362  if ( status != QProcess::NormalExit || exitCode != 0 )
1363  {
1364     installFailed();
1365  } else {
1366    // Move to the final page, and show a finish button
1367    proceed(true);
1368    nextButton->setEnabled(true);
1369    nextButton->setText(tr("&Finish"));
1370    nextButton->disconnect();
1371    connect(nextButton, SIGNAL(clicked()), this, SLOT(slotFinished()));
1372    backButton->setEnabled(false);
1373    abortButton->setEnabled(false);
1374  }
1375}
1376
1377// Slot which reads the output of the installer
1378void Installer::slotReadInstallerOutput()
1379{
1380  QString tmp, line;
1381  int range;
1382  bool ok;
1383
1384
1385  while ( installProc->canReadLine() )
1386  {
1387     tmp = installProc->readLine();
1388     tmp.truncate(75);
1389     //qDebug() << tmp;
1390
1391     // If doing a restore, don't bother checking for other values
1392     //if ( radioRestore->isChecked() ) {
1393     //   labelInstallStatus->setText(tmp);
1394     // continue;
1395     //}
1396
1397     // Parse fetch output
1398     if ( installFoundFetchOutput ) {
1399       if ( tmp.indexOf("SIZE: ") != -1 ) {
1400
1401          // Get the total range first
1402          line = tmp;
1403          tmp = tmp.remove(0, tmp.indexOf(":") + 2 );
1404          tmp.truncate(tmp.indexOf(" ")); 
1405          range = tmp.toInt(&ok);
1406          if ( ok )
1407             progressBarInstall->setRange(0, range + 1);
1408
1409          // Now get the current progress
1410          tmp = line;
1411          tmp = tmp.remove(0, tmp.indexOf(":") + 2 );
1412          tmp = tmp.remove(0, tmp.indexOf(":") + 2 );
1413          range = tmp.toInt(&ok);
1414          if ( ok )
1415             progressBarInstall->setValue(range);
1416           
1417          continue;
1418        } else {
1419          installFoundFetchOutput = false;
1420          break;
1421        }
1422     } 
1423
1424     // Unknown point in install
1425     if ( ! installFoundCounter && ! installFoundMetaCounter ) {
1426
1427        // Check if we've found fetch output to update the progress bar with
1428        if ( tmp.indexOf("FETCH: ") != -1 ) {
1429          installFoundFetchOutput = true;
1430          break;
1431        }
1432
1433        if ( tmp.indexOf("INSTALLCOUNT: ") != -1 ) {
1434          tmp = tmp.remove(0, tmp.indexOf(":") + 1 ); 
1435          range = tmp.toInt(&ok);
1436          if ( ok ) {
1437             range = range + 50;
1438             progressBarInstall->setRange(0, range + 1); 
1439             installFoundCounter = true;
1440             if ( availDesktopPackageData )
1441                labelInstallStatus->setText(tr("Extracting system...")); 
1442             else
1443                labelInstallStatus->setText(tr("Installing system... This may take a while...")); 
1444          }
1445
1446          break;
1447
1448        } 
1449
1450        // Check if we are on the meta-pkg installation
1451        if ( tmp.indexOf("Packages to install: ") != -1 ) {
1452          tmp = tmp.remove(0, tmp.indexOf(":") + 1 ); 
1453          range = tmp.toInt(&ok);
1454          if ( ok ) {
1455             progressBarInstall->setRange(0, range + 1); 
1456             progressBarInstall->setValue(0); 
1457             progressBarInstall2->setRange(0, 0); 
1458             labelInstallStatus2->setHidden(false);
1459             progressBarInstall2->setHidden(false); 
1460             installFoundMetaCounter = true;
1461             installFoundCounter = false;
1462             labelInstallStatus->setText(tr("Installing packages... This may take a while...")); 
1463             continue;
1464          }
1465
1466        } 
1467
1468        labelInstallStatus->setText(tmp);
1469        continue; 
1470     } 
1471
1472     // Doing file-extraction still
1473     if ( installFoundCounter ) {
1474
1475       // Doing dist-files, may have multiple images to extract
1476       if ( tmp.indexOf("INSTALLCOUNT: ") != -1 ) {
1477         tmp = tmp.remove(0, tmp.indexOf(":") + 1 ); 
1478         range = tmp.toInt(&ok);
1479         if ( ok ) {
1480            progressBarInstall->setRange(0, range + 1); 
1481            installFoundCounter = true;
1482            if ( availDesktopPackageData )
1483              labelInstallStatus->setText(tr("Extracting system...")); 
1484            else
1485              labelInstallStatus->setText(tr("Installing system... This may take a while...")); 
1486         }
1487         break;
1488       } 
1489
1490
1491       // Increment the progress
1492       progressBarInstall->setValue(progressBarInstall->value() + 1); 
1493
1494       // We've reached the end of this counted section
1495       if ( tmp.indexOf("Extraction Finished") != -1 ) {
1496         installFoundCounter = false;
1497         progressBarInstall->setRange(0, 0); 
1498       }
1499
1500       continue;
1501     }
1502
1503     // Doing meta-pkgs
1504     if ( installFoundMetaCounter ) {
1505        if ( tmp.indexOf("Package installation complete!") != -1 ) {
1506           installFoundMetaCounter = false;
1507           progressBarInstall->setRange(0, 0); 
1508           progressBarInstall2->setHidden(true);
1509           labelInstallStatus2->setHidden(true);
1510           continue;
1511        }
1512
1513        // Got this far, increment the pkg-sub count
1514        progressBarInstall->setValue(progressBarInstall->value() + 1); 
1515        labelInstallStatus2->setText(tmp);
1516     }
1517
1518  } // end of while loop
1519}
1520
1521// Return list of components to install
1522QStringList Installer::getComponentCfgSettings()
1523{
1524  QStringList componentList, com;
1525  if ( fSRC )
1526    com << "src";
1527  if ( fPORTS )
1528    com << "ports";
1529
1530  if ( ! com.isEmpty() ) {
1531    componentList << "";
1532    componentList << "# Optional Components";
1533    componentList << "installComponents=" + com.join(",");
1534  }
1535
1536  return componentList;
1537}
1538
1539// Start xvkbd
1540void Installer::slotPushVirtKeyboard()
1541{
1542   system("killall -9 xvkbd; xvkbd -compact &");
1543}
1544
1545// Return the configuration for desktop packages
1546QStringList Installer::getDeskPkgCfg()
1547{
1548   if ( wheelCurItem == wFREEBSD )
1549      return QStringList();
1550
1551   QStringList cfgList, pkgList;
1552   QString line;
1553
1554   QList<QStringList> curList;
1555
1556   if ( wheelCurItem != wPCSERVER && wheelCurItem != 11 && wheelCurItem != 12) {
1557     curList = listDeskPkgs;
1558     pkgList << "pcbsd-base";
1559   } else {
1560     curList = listServerPkgs;
1561     pkgList << "trueos-base";
1562   }
1563
1564   // Loop though list of pkgs, see what to install
1565   for ( int d=0; d < curList.count(); ++d) {
1566     for ( int i=0; i < selectedPkgs.count(); ++i)
1567        // Is the package selected or the base-system?
1568        if ( curList.at(d).at(0) == selectedPkgs.at(i) || curList.at(d).at(0) == "base-system" ) {
1569
1570           // Yay! Lets get a list of packages to install
1571           QFile mFile;
1572           mFile.setFileName(curList.at(d).at(6));
1573           if ( ! mFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
1574              qDebug() << "Invalid meta-pkg list:" << curList.at(d).at(6);
1575              break;
1576           }
1577 
1578           // Read in the meta pkg list
1579           QTextStream in(&mFile);
1580           while ( !in.atEnd() ) {
1581             line = in.readLine().simplified();
1582             if ( line.isEmpty() )
1583                 continue; 
1584             
1585             pkgList << line.section(":", 0,0);
1586           }
1587           mFile.close();
1588           break;
1589        }
1590   }
1591
1592   cfgList << "installPackages=" + pkgList.join(" ");
1593   return cfgList;
1594}
1595
1596// Return list of users in cfg format
1597QStringList Installer::getUsersCfgSettings()
1598{
1599   QStringList userList;
1600 
1601   userList << "";
1602   userList << "# Root Password";
1603   userList << "rootPass=" + fRootPW;
1604
1605   userList << "";
1606   userList << "# Users";
1607   userList << "userName=" + fUserName;
1608   userList << "userComment=" + fName;
1609   userList << "userPass=" + fUserPW;
1610   userList << "userShell=" + fShell;
1611   userList << "userHome=/home/" + fUserName;
1612   userList << "userGroups=wheel,operator";
1613   userList << "commitUser";
1614   userList << "";
1615 
1616   return userList;
1617}
1618
1619void Installer::closeEvent(QCloseEvent *event)
1620{
1621    int ret = QMessageBox::question(this, tr("PC-BSD Installer"),
1622                                tr("Are you sure you want to abort this installation?"),
1623                                QMessageBox::No | QMessageBox::Yes,
1624                                QMessageBox::No);
1625    switch (ret) {
1626    case QMessageBox::Yes:
1627        //exit the installer :(
1628        break;
1629    case QMessageBox::No: // :)
1630        event->ignore();
1631        break;
1632    }
1633}
1634
1635void Installer::checkSpaceWarning()
1636{
1637  int totalSize = -1;
1638  int targetSize;
1639  int targetLoc;
1640  bool ok;
1641  QString workingDisk = sysFinalDiskLayout.at(0).at(0);
1642  QString workingSlice = sysFinalDiskLayout.at(0).at(1);
1643  QString targetType;
1644  QString target;
1645  //qDebug() << "Disk layout:" << workingDisk << workingSlice;
1646
1647  if ( workingSlice == "ALL" ) {
1648    targetType = "DRIVE";
1649    target = workingDisk;
1650    targetLoc = 1;
1651  } else {
1652    targetType = "SLICE";
1653    target = workingDisk + workingSlice;
1654    targetLoc = 2;
1655  }
1656 
1657  // Lets get the size for this disk / partition
1658  for (int i=0; i < sysDisks.count(); ++i) {
1659      // Make sure to only add the slices to the listDiskSlices
1660      if ( sysDisks.at(i).at(0) == targetType && target == sysDisks.at(i).at(targetLoc))
1661        totalSize = sysDisks.at(i).at(targetLoc + 1).toInt(&ok);
1662  }
1663
1664  //qDebug() << totalSize;
1665
1666  if ( installStackWidget->currentIndex() == 1 && (wheelCurItem == wFREEBSD || wheelCurItem == wPCSERVER || wheelCurItem == 12) )
1667     targetSize=20000;
1668  else
1669     targetSize=50000;
1670
1671  qDebug() << totalSize << targetSize;
1672
1673  // Lets print a nice handy warning for users with possible
1674  // low disk space issues
1675  if ( totalSize < targetSize ) {
1676  QMessageBox::warning(this, tr("PC-BSD Installer"),
1677      QString(tr("The selected disk / partition is less than recommended %1MB. The installation may fail...")).arg(targetSize),
1678      QMessageBox::Ok,
1679      QMessageBox::Ok);
1680      haveWarnedSpace = true;     
1681  }
1682
1683  return;
1684}
Note: See TracBrowser for help on using the repository browser.