source: src-qt4/pc-pkgmanager/mainWin.cpp @ 98b904e

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 98b904e was 98b904e, checked in by Kris Moore <kris@…>, 20 months ago

Fix a bug preventing us from running a fresh package update check
after doing an update

  • Property mode set to 100644
File size: 23.3 KB
Line 
1/****************************************************************************
2** ui.h extension file, included from the uic-generated form implementation.
3**
4** If you want to add, delete, or rename functions or slots, use
5** Qt Designer to update this file, preserving your code.
6**
7** You should not define a constructor or destructor in this file.
8** Instead, write your code in functions called init() and destroy().
9** These will automatically be called by the form's constructor and
10** destructor.
11*****************************************************************************/
12#include <fcntl.h>
13#include <QDateTime>
14#include <QDebug>
15#include <QDir>
16#include <QProcess>
17#include <QProgressDialog>
18#include <QSocketNotifier>
19#include <QString>
20#include <QTextStream>
21#include <pcbsd-utils.h>
22#include <pcbsd-ui.h>
23#include "mainWin.h"
24#include "../config.h"
25
26void mainWin::ProgramInit(QString ch)
27{
28  // Set any warden directories
29  lastError="";
30  wDir = ch;
31
32  //Grab the username
33  //username = QString::fromLocal8Bit(getenv("LOGNAME"));
34  connect(pushUpdatePkgs, SIGNAL(clicked()), this, SLOT(slotUpdatePkgsClicked()));
35  connect(pushClose, SIGNAL(clicked()), this, SLOT(slotCloseClicked()));
36  connect(buttonRescanPkgs, SIGNAL(clicked()), this, SLOT(slotRescanPkgsClicked()));
37  connect(pushPkgApply, SIGNAL( clicked() ), this, SLOT( slotApplyClicked() ) );
38
39  QTimer::singleShot(200, this, SLOT(slotRescanPkgsClicked() ) );
40  initMetaWidget();
41}
42
43void mainWin::slotRescanPkgsClicked()
44{
45  // Check for pkg updates
46  checkMPKGUpdates();
47}
48
49void mainWin::slotApplyClicked() {
50
51}
52
53void mainWin::checkMPKGUpdates() {
54
55  QString line, tmp, name, pkgname, pkgover, pkgnver;
56  QStringList up, listPkgs;
57  bool haveUpdates = false;
58  int totPkgs=0;
59  buttonRescanPkgs->setEnabled(false);
60  pushUpdatePkgs->setEnabled(false);
61  listViewUpdatesPkgs->clear();
62  groupUpdatesPkgs->setTitle(tr("Checking for updates"));
63
64  QProcess p;
65  if ( wDir.isEmpty() )
66     p.start(QString("pc-updatemanager"), QStringList() << "pkgcheck");
67  else
68     p.start(QString("chroot"), QStringList() << wDir << "pc-updatemanager" << "pkgcheck");
69  while(p.state() == QProcess::Starting || p.state() == QProcess::Running)
70     QCoreApplication::processEvents();
71
72  while (p.canReadLine()) {
73    line = p.readLine().simplified();
74    qDebug() << line;
75    if ( line.indexOf("Upgrading") != 0) {
76       continue;
77    }
78    tmp = line;
79    pkgname = tmp.section(" ", 1, 1);
80    pkgname.replace(":", "");
81    pkgover = tmp.section(" ", 2, 2);
82    pkgnver = tmp.section(" ", 4, 4);
83    QTreeWidgetItem *myItem = new QTreeWidgetItem(QStringList() << pkgname << pkgover << pkgnver);
84    listViewUpdatesPkgs->addTopLevelItem(myItem);
85    haveUpdates = true;
86    totPkgs++;
87  }
88
89  buttonRescanPkgs->setEnabled(true);
90  pushUpdatePkgs->setEnabled(haveUpdates);
91  if ( totPkgs > 0 ) {
92    tabUpdates->setTabText(1, tr("Package Updates (%1)").arg(totPkgs));
93    groupUpdatesPkgs->setTitle(tr("Available updates"));
94  } else {
95    tabUpdates->setTabText(1, tr("Package Updates"));
96    groupUpdatesPkgs->setTitle(tr("No available updates"));
97  }
98 
99}
100
101void mainWin::slotSingleInstance() {
102   this->hide();
103   this->showNormal();
104   this->activateWindow();
105   this->raise();
106}
107
108void mainWin::slotCloseClicked() {
109   close();
110}
111
112void mainWin::slotUpdatePkgsClicked() {
113  dPackages = false;
114  uPackages = false;
115
116  // Init the pkg process
117  prepPkgProcess();
118
119  // Create our runlist of package commands
120  QStringList pCmds;
121
122  if ( wDir.isEmpty() )
123    pCmds << "pc-updatemanager" << "pkgupdate";
124  else
125    pCmds << "chroot" << wDir << "pc-updatemanager" << "pkgupdate";
126
127  // Setup our runList
128  pkgCmdList << pCmds;
129
130  // Start the updating now
131  startPkgProcess();
132
133  textStatus->setText(tr("Starting package updates..."));
134
135}
136
137void mainWin::prepPkgProcess() {
138  pkgCmdList.clear();
139  textDisplayOut->clear();
140  pkgHasFailed=false;
141}
142
143void mainWin::startPkgProcess() {
144
145  if ( pkgCmdList.isEmpty() )
146    return;
147  if ( pkgCmdList.at(0).at(0).isEmpty() )
148     return; 
149
150  // Get the command name
151  QString cmd;
152  cmd = pkgCmdList.at(0).at(0);
153
154  // Get any optional flags
155  QStringList flags;
156  for (int i = 0; i < pkgCmdList.at(0).size(); ++i) {
157     if ( i == 0 )
158       continue;
159     flags << pkgCmdList.at(0).at(i);
160  } 
161
162  qDebug() << cmd + " " + flags.join(" ");
163 
164  // Setup the first process
165  uProc = new QProcess();
166  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
167  env.insert("PCFETCHGUI", "YES");
168  uProc->setProcessEnvironment(env);
169  uProc->setProcessChannelMode(QProcess::MergedChannels);
170
171  // Connect the slots
172  connect( uProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotReadPkgOutput()) );
173  connect( uProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotPkgDone()) );
174
175  uProc->start(cmd, flags);
176
177  stackedTop->setCurrentIndex(1);
178
179  progressUpdate->setRange(0, 0 );
180  progressUpdate->setValue(0);
181
182}
183
184void mainWin::slotReadPkgOutput() {
185   QString line, tmp, cur, tot, fname;
186
187   while (uProc->canReadLine()) {
188     line = uProc->readLine().simplified();
189     qDebug() << line;
190
191     tmp = line;
192     tmp.truncate(50);
193
194     // Flags we can parse out and not show the user
195
196     // Check if we have crashed into a conflict and ask the user what to do
197     if ( line.indexOf("PKGCONFLICTS: ") == 0 ) {
198        tmp = line; 
199        tmp.replace("PKGCONFLICTS: ", "");
200        ConflictList = tmp;
201        continue;
202     }
203     if ( line.indexOf("PKGREPLY: ") == 0 ) {
204        QString ans;
205        tmp = line; 
206        tmp.replace("PKGREPLY: ", "");
207        if ( QMessageBox::Yes == QMessageBox::warning(this, tr("Package Conflicts"),
208          tr("The following packages are causing conflicts with the selected changes and can be automatically removed. Continue?") + "\n" + ConflictList,
209          QMessageBox::Yes|QMessageBox::No,
210          QMessageBox::Yes) ) {
211
212          // We will try to fix conflicts
213          ans="yes";
214           
215        } else {
216          // We will fail :(
217          QMessageBox::warning(this, tr("Package Conflicts"),
218          tr("You may need to manually fix the conflicts before trying again."),
219          QMessageBox::Ok,
220          QMessageBox::Ok);
221          ans="no";
222        }
223
224        QFile pkgTrig( tmp );
225        if ( pkgTrig.open( QIODevice::WriteOnly ) ) {
226           QTextStream streamTrig( &pkgTrig );
227           streamTrig << ans;
228           pkgTrig.close();
229        }
230     }
231
232     if ( line.indexOf("FETCH: ") == 0 ) { 
233        progressUpdate->setValue(progressUpdate->value() + 1); 
234        tmp = line; 
235        tmp = tmp.remove(0, tmp.lastIndexOf("/") + 1); 
236        progressUpdate->setRange(0, 0);
237        progressUpdate->setValue(0);
238        curFileText = tr("Downloading: %1").arg(tmp); 
239        textStatus->setText(tr("Downloading: %1").arg(tmp)); 
240        continue;
241     } 
242     if ( line.indexOf("FETCHDONE") == 0 )
243        continue;
244
245     if ( line.indexOf("SIZE: ") == 0 ) {
246          bool ok, ok2;
247          line.replace("SIZE: ", "");
248          line.replace("DOWNLOADED: ", "");
249          line.replace("SPEED: ", "");
250          line.section(" ", 0, 0).toInt(&ok);
251          line.section(" ", 1, 1).toInt(&ok2);
252   
253          if ( ok && ok2 ) {
254            QString unit;
255            int tot = line.section(" ", 0, 0).toInt(&ok);
256            int cur = line.section(" ", 1, 1).toInt(&ok2);
257            QString percent = QString::number( (float)(cur * 100)/tot );
258            QString speed = line.section(" ", 2, 3);
259
260            // Get the MB downloaded / total
261            if ( tot > 2048 ) {
262              unit="MB";
263              tot = tot / 1024;
264              cur = cur / 1024;
265            } else {
266              unit="KB";
267            }
268
269            QString ProgressString=QString("(%1" + unit + " of %2" + unit + " at %3)").arg(cur).arg(tot).arg(speed);
270            progressUpdate->setRange(0, tot);
271            progressUpdate->setValue(cur);
272            textStatus->setText(curFileText + " " + ProgressString); 
273         }
274         continue;
275     }
276
277
278     // Now show output on GUI
279     textDisplayOut->insertPlainText(line + "\n");
280     textDisplayOut->moveCursor(QTextCursor::End);
281
282
283     // Any other flags to look for?
284     /////////////////////////////////////////////////////
285     if ( line.indexOf("to be downloaded") != -1 ) {
286       textStatus->setText(tr("Downloading packages..."));
287       curUpdate = 0;
288       progressUpdate->setValue(0);
289       continue;
290     }
291     if ( line.indexOf("Checking integrity") == 0 ) {
292       textStatus->setText(line);
293       uPackages = true;
294       dPackages = false;
295       curUpdate = 0;
296       progressUpdate->setValue(0);
297     }
298     
299     if ( uPackages ) {
300       if ( line.indexOf("Upgrading") == 0 ) {
301         textStatus->setText(line);
302         curUpdate++;
303         progressUpdate->setValue(curUpdate);
304       }
305       continue;
306     }
307
308   } // end of while
309}
310
311void mainWin::slotPkgDone() {
312
313  if ( uProc->exitCode() != 0 )
314    pkgHasFailed=true;
315
316  // Run the next command on the stack if necessary
317  if (  pkgCmdList.size() > 1 ) {
318        pkgCmdList.removeAt(0); 
319        startPkgProcess();     
320        return;
321  }
322
323  // Nothing left to run! Lets wrap up
324  QFile sysTrig( SYSTRIGGER );
325  if ( sysTrig.open( QIODevice::WriteOnly ) ) {
326    QTextStream streamTrig( &sysTrig );
327     streamTrig << "INSTALLFINISHED: ";
328  }
329
330  if ( pkgHasFailed ) {
331    QFile file( "/tmp/pkg-output.log" );
332    if ( file.open( QIODevice::WriteOnly ) ) {
333       QTextStream stream( &file );
334       stream << textDisplayOut->toPlainText();
335       file.close();
336    }
337    QMessageBox::warning(this, tr("Failed!"), tr("The package commands failed. A copy of the output was saved to /tmp/pkg-output.log"));
338  } else
339    QMessageBox::warning(this, tr("Finished!"), tr("Package changes complete!" ));
340
341  stackedTop->setCurrentIndex(0);
342
343}
344
345/*****************************************
346Code for meta-package (Basic Mode)
347******************************************/
348
349void mainWin::initMetaWidget()
350{
351  qDebug() << "Starting metaWidget...";
352
353  populateMetaPkgs();
354
355  // Connect our slots
356  treeMetaPkgs->setContextMenuPolicy(Qt::CustomContextMenu);
357  connect(treeMetaPkgs, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotMetaRightClick()) );
358
359
360}
361
362
363// Display found meta-pkg data
364void mainWin::populateMetaPkgs()
365{
366  pushPkgApply->setEnabled(false);
367  treeMetaPkgs->clear();
368  tmpMetaPkgList.clear();
369  new QTreeWidgetItem(treeMetaPkgs, QStringList() << tr("Loading... Please wait...") );
370
371  if ( ! metaPkgList.isEmpty() )
372        disconnect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), 0, 0);
373  metaPkgList.clear();
374
375  // Start the process to get meta-pkg info
376  getMetaProc = new QProcess();
377  qDebug() << "Searching for meta-pkgs...";
378  connect( getMetaProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotGetPackageDataOutput()) );
379  connect( getMetaProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishLoadingMetaPkgs()) );
380  getMetaProc->setProcessChannelMode(QProcess::MergedChannels);
381  getMetaProc->start(QString("pc-metapkgmanager"), QStringList() << chrootArg1 << chrootArg2 << "list");
382
383}
384
385// Display found meta-pkg data
386void mainWin::slotFinishLoadingMetaPkgs()
387{
388
389  // Populate the metaPkgList
390  parseTmpMetaList();
391
392  treeMetaPkgs->clear();
393
394  addTreeItems(QString()); 
395
396  connect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotDeskPkgsChanged(QTreeWidgetItem *, int)));
397}
398
399void mainWin::addTreeItems(QString parent)
400{
401  for (int z=0; z < metaPkgList.count(); ++z) {
402    if ( metaPkgList.at(z).at(3) != parent )
403      continue;
404
405    // Hide the "base-system" package, since we are installing it anyway
406    if (metaPkgList.at(z).at(0) == "base-system" )
407      return;
408
409    QTreeWidgetItem *deskItem = new QTreeWidgetItem(QStringList() << metaPkgList.at(z).at(0) );
410    deskItem->setIcon(0, QIcon(metaPkgList.at(z).at(2)));
411    deskItem->setToolTip(0, metaPkgList.at(z).at(1));
412    deskItem->setCheckState(0, Qt::Unchecked);
413
414    if ( metaPkgList.at(z).at(5) == "YES" )
415      deskItem->setCheckState(0, Qt::Checked);
416
417    if ( parent.isEmpty() ) {
418      treeMetaPkgs->addTopLevelItem(deskItem);
419    } else {
420      // Locate the parent to attach to
421      QTreeWidgetItemIterator it(treeMetaPkgs);
422      while (*it) {
423        if ((*it)->text(0) == parent ) {
424          (*it)->addChild(deskItem);
425          if ( metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked)
426            (*it)->setCheckState(0, Qt::PartiallyChecked);
427          if ( metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked)
428            (*it)->setCheckState(0, Qt::PartiallyChecked);
429          break;
430        }
431        it++;
432      }
433    }
434
435    // Now look for any possible children
436    addTreeItems(metaPkgList.at(z).at(0));   
437  }
438}
439
440// Check if a meta-pkg is installed
441bool mainWin::isMetaPkgInstalled(QString mPkg)
442{
443  QString tmp;
444  QProcess pcmp;
445  pcmp.start(QString("pc-metapkgmanager"), QStringList() << chrootArg1 << chrootArg2 << "status" << mPkg);
446  while ( pcmp.state() != QProcess::NotRunning ) {
447     pcmp.waitForFinished(50);
448     QCoreApplication::processEvents();
449  }
450
451  while (pcmp.canReadLine()) {
452     tmp = pcmp.readLine().simplified();
453     if ( tmp.indexOf("is installed") != -1 )
454     return true;
455  }
456
457  return false;
458}
459
460// Function which checks for our GUI package schema data
461void mainWin::slotGetPackageDataOutput()
462{
463  while (getMetaProc->canReadLine())
464        tmpMetaPkgList << getMetaProc->readLine().simplified();
465}
466
467// Parse the pc-metapkg saved output
468void mainWin::parseTmpMetaList()
469{
470  QString tmp, mName, mDesc, mIcon, mParent, mDesktop, mInstalled, mPkgFileList;
471  QStringList package;
472
473  for ( int i = 0 ; i < tmpMetaPkgList.size(); i++ )
474  {
475        QApplication::processEvents();
476
477        tmp = tmpMetaPkgList.at(i);
478
479        if ( tmp.indexOf("Meta Package: ") == 0) {
480                mName = tmp.replace("Meta Package: ", "");
481                continue;
482        }
483        if ( tmp.indexOf("Description: ") == 0) {
484                mDesc = tmp.replace("Description: ", "");
485                continue;
486        }
487        if ( tmp.indexOf("Icon: ") == 0) {
488                mIcon = tmp.replace("Icon: ", "");
489                mPkgFileList = mIcon;
490                mPkgFileList.replace("pkg-icon.png", "pkg-list");
491                continue;
492        }
493        if ( tmp.indexOf("Parent: ") == 0) {
494                mParent = tmp.replace("Parent: ", "");
495                continue;
496        }
497        if ( tmp.indexOf("Desktop: ") == 0) {
498                mDesktop = tmp.replace("Desktop: ", "");
499                continue;
500        }
501
502        // This is an empty category
503        if ( tmp.indexOf("Category Entry") == 0) {
504                // Now add this category to the string list
505                package.clear();
506                qDebug() << "Found Package" << mName << mDesc << mIcon << mParent << mDesktop;
507                mInstalled = "CATEGORY";
508                package << mName << mDesc << mIcon << mParent << mDesktop << mInstalled;
509                metaPkgList.append(package);
510                mName=""; mDesc=""; mIcon=""; mParent=""; mDesktop=""; mInstalled=""; mPkgFileList="";
511        }
512
513        // We have a Meta-Pkg
514        if ( tmp.indexOf("Required Packages:") == 0) {
515                // Now add this meta-pkg to the string list
516                package.clear();
517                qDebug() << "Found Package" << mName << mDesc << mIcon << mParent << mDesktop << mPkgFileList;
518
519                if ( isMetaPkgInstalled(mName) )
520                        mInstalled = "YES";
521                else
522                        mInstalled = "NO";
523
524                package << mName << mDesc << mIcon << mParent << mDesktop << mInstalled << mPkgFileList;
525                metaPkgList.append(package);
526                mName=""; mDesc=""; mIcon=""; mParent=""; mDesktop=""; mInstalled=""; mPkgFileList="";
527        }
528
529    }
530
531}
532
533void mainWin::saveMetaPkgs()
534{
535        if ( ! haveMetaPkgChanges() )
536                return;
537
538        addPkgs = getAddPkgs();
539        delPkgs = getDelPkgs(); 
540
541        startMetaChanges();
542
543}
544
545void mainWin::startMetaChanges()
546{
547
548  // Init the pkg process
549  prepPkgProcess();
550  // Create our runlist of package commands
551  QStringList pCmds;
552
553  if ( ! delPkgs.isEmpty() ) {
554    if ( wDir.isEmpty() )
555      pCmds << "pc-metapkgmanager" << "del" << delPkgs;
556    else 
557      pCmds << "chroot" << wDir << "pc-metapkgmanager" << "del" << delPkgs;
558    pkgCmdList << pCmds;
559  }
560 
561  pCmds.clear();
562
563  if ( ! addPkgs.isEmpty() ) {
564    if ( wDir.isEmpty() )
565      pCmds << "pc-metapkgmanager" << "add" << addPkgs;
566    else 
567      pCmds << "chroot" << wDir << "pc-metapkgmanager" << "add" << addPkgs;
568    pkgCmdList << pCmds;
569  }
570
571  // Lets kick it off now
572  startPkgProcess();
573}
574
575bool mainWin::haveAMetaDesktop()
576{
577        // If running in a chroot we can skip this check
578        if ( ! chrootArg1.isEmpty() )
579          return true;
580       
581        QTreeWidgetItemIterator it(treeMetaPkgs);
582        while (*it) {
583         if ( ((*it)->checkState(0) == Qt::Checked) || ((*it)->checkState(0) == Qt::PartiallyChecked) )
584           for (int z=0; z < metaPkgList.count(); ++z)
585             if ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(4) == "YES" )
586                return true;
587         ++it;
588        }
589
590        QMessageBox::warning(this, tr("No Desktop"),
591          tr("No desktops have been selected! Please choose at least one desktop before saving."),
592          QMessageBox::Ok,
593          QMessageBox::Ok);
594
595        return false;
596}
597
598bool mainWin::haveMetaPkgChanges()
599{
600        QTreeWidgetItemIterator it(treeMetaPkgs);
601        while (*it) {
602          for (int z=0; z < metaPkgList.count(); ++z)
603            // See if any packages status have changed
604            if ( ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked ) \
605              || ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::PartiallyChecked ) \
606              || ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked ) )
607                return true;
608         ++it;
609        }
610
611        return false;
612}
613
614QString mainWin::getAddPkgs()
615{
616        QString tmp;
617        QTreeWidgetItemIterator it(treeMetaPkgs);
618        while (*it) {
619          for (int z=0; z < metaPkgList.count(); ++z)
620            // See if any packages status have changed
621            if ( ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked ) || \
622                 ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::PartiallyChecked ) )
623                if ( tmp.isEmpty() )
624                        tmp = (*it)->text(0);
625                else
626                        tmp = tmp + "," + (*it)->text(0);
627         ++it;
628        }
629
630        return tmp;
631}
632
633QString mainWin::getDelPkgs()
634{
635        QString tmp;
636        QTreeWidgetItemIterator it(treeMetaPkgs);
637        while (*it) {
638          for (int z=0; z < metaPkgList.count(); ++z)
639            // See if any packages status have changed
640            if ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked )
641                if ( tmp.isEmpty() )
642                        tmp = (*it)->text(0);
643                else
644                        tmp = tmp + "," + (*it)->text(0);
645         ++it;
646        }
647
648        return tmp;
649}
650
651
652// Time to save meta-pkgs
653void mainWin::slotApplyMetaChanges() {
654    saveMetaPkgs();
655}
656
657
658
659// The User changed the tree widget checked / unchecked stuff sanity check
660void mainWin::slotDeskPkgsChanged(QTreeWidgetItem *aItem, int __unused)
661{
662        if (!aItem)
663          return;
664
665        disconnect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), 0, 0);
666
667        if (aItem->childCount() == 0) {
668                if (aItem->checkState(0) == Qt::Checked && aItem->parent() )
669                        if ( allChildrenPkgsChecked(aItem->parent()->text(0)))
670                                aItem->parent()->setCheckState(0, Qt::Checked); 
671                        else
672                                aItem->parent()->setCheckState(0, Qt::PartiallyChecked);       
673                if (aItem->checkState(0) == Qt::Unchecked && aItem->parent() )
674                        if ( ! allChildrenPkgsUnchecked(aItem->parent()->text(0)))
675                                aItem->parent()->setCheckState(0, Qt::PartiallyChecked);       
676
677
678        } else {
679                if (aItem->checkState(0) == Qt::Checked )
680                        checkAllChildrenPkgs(aItem->text(0));
681                else
682                        uncheckAllChildrenPkgs(aItem->text(0));
683        }
684       
685
686    connect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotDeskPkgsChanged(QTreeWidgetItem *, int)));
687
688        if ( haveMetaPkgChanges() )
689                pushPkgApply->setEnabled(true);
690        else
691                pushPkgApply->setEnabled(false);
692}
693
694// Check the "parent" app to see if all its children are checked or not
695bool mainWin::allChildrenPkgsChecked(QString parent)
696{
697        QTreeWidgetItemIterator it(treeMetaPkgs);
698        while (*it) {
699         if ((*it)->text(0) == parent ) {
700           if ( (*it)->childCount() <= 0)
701             return true;
702
703           for ( int i = 0; i < (*it)->childCount() ; ++i) {
704             if ( ! allChildrenPkgsChecked((*it)->child(i)->text(0)))
705               return false;
706
707             if ((*it)->child(i)->checkState(0) != Qt::Checked ) 
708               return false;
709           }
710         }
711         ++it;
712        }
713        return true;
714}
715
716// Check the "parent" app to see if all its children are unchecked or not
717bool mainWin::allChildrenPkgsUnchecked(QString parent)
718{
719        QTreeWidgetItemIterator it(treeMetaPkgs);
720        while (*it) {
721         if ((*it)->text(0) == parent ) {
722           if ( (*it)->childCount() <= 0)
723             return true;
724
725           for ( int i = 0; i < (*it)->childCount() ; ++i) {
726             if ( ! allChildrenPkgsUnchecked((*it)->child(i)->text(0)))
727               return false;
728
729             if ((*it)->child(i)->checkState(0) != Qt::Unchecked ) 
730               return false;
731           }
732         }
733         ++it;
734        }
735        return true;
736}
737
738// Check all children of parent
739void mainWin::checkAllChildrenPkgs(QString parent)
740{
741        QTreeWidgetItemIterator it(treeMetaPkgs);
742        while (*it) {
743         if (! (*it)->parent()) {
744           ++it;
745           continue;
746         } 
747
748         // Lets walk the tree see what pops up
749         bool pFound=false;
750         QTreeWidgetItem *itP = (*it)->parent();
751         do {
752           pFound=false;
753           if (itP->text(0) == parent) {
754             (*it)->setCheckState(0, Qt::Checked);
755             break;
756           }
757           if ( itP->parent() ) {
758             itP = itP->parent();
759             pFound=true;
760           }
761         } while (pFound);
762
763         ++it;
764       }
765}
766
767// UnCheck all children of parent
768void mainWin::uncheckAllChildrenPkgs(QString parent)
769{
770        QTreeWidgetItemIterator it(treeMetaPkgs);
771        while (*it) {
772         if (! (*it)->parent()) {
773           ++it;
774           continue;
775         } 
776
777         // Lets walk the tree see what pops up
778         bool pFound=false;
779         QTreeWidgetItem *itP = (*it)->parent();
780         do {
781           pFound=false;
782           if (itP->text(0) == parent) {
783             (*it)->setCheckState(0, Qt::Unchecked);
784             break;
785           }
786           if ( itP->parent() ) {
787             itP = itP->parent();
788             pFound=true;
789           }
790         } while (pFound);
791
792         ++it;
793       }
794}
795
796void mainWin::slotMetaRightClick()
797{
798        QTreeWidgetItemIterator it(treeMetaPkgs);
799        while (*it) {
800          for (int z=0; z < metaPkgList.count(); ++z) {
801            if ( (*it)->isSelected() && (*it)->text(0) == metaPkgList.at(z).at(0) ) {
802              if (metaPkgList.at(z).at(5) == "CATEGORY")
803                return;
804              popup = new QMenu;
805              popup->setTitle((*it)->text(0));
806              popup->addAction(tr("View Packages"), this, SLOT(slotMetaViewPkgs()));
807              popup->exec( QCursor::pos() );
808            }
809          }
810         ++it;
811        }
812}
813
814void mainWin::slotMetaViewPkgs()
815{
816        QStringList packageList;
817        QTreeWidgetItemIterator it(treeMetaPkgs);
818        while (*it) {
819          for (int z=0; z < metaPkgList.count(); ++z) {
820            if ( (*it)->isSelected() && (*it)->text(0) == metaPkgList.at(z).at(0) ) {
821 
822                QFile pList(metaPkgList.at(z).at(6));
823                if ( ! pList.exists() )
824                  return;
825               
826                if ( ! pList.open(QIODevice::ReadOnly | QIODevice::Text))
827                  return;
828
829                while ( !pList.atEnd() )
830                  packageList << pList.readLine().simplified();
831
832                pList.close();
833                packageList.sort();
834                       
835                dIB = new dialogInfo();
836                dIB->programInit(tr("Package Listing for:") + " " + (*it)->text(0));
837                dIB->setInfoText(packageList.join("\n"));
838                dIB->show();
839            }
840          }
841         ++it;
842        }
843}
844
845QString mainWin::getLineFromCommandOutput( QString cmd )
846{
847        FILE *file = popen(cmd.toLatin1(),"r");
848 
849        char buffer[100];
850 
851        QString line = "";
852        char firstChar;
853
854        if ((firstChar = fgetc(file)) != -1){
855                line += firstChar;
856                line += fgets(buffer,100,file);
857        }
858        pclose(file);
859        return line.simplified();
860}
Note: See TracBrowser for help on using the repository browser.