source: src-qt4/pc-pkgmanager/mainWin.cpp @ 4c06449

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2
Last change on this file since 4c06449 was 4c06449, checked in by Kris Moore <kris@…>, 15 months ago

Add all the new pkg conflict logic to libsh

Will detect if something is going to fail during pkg process and
warn the user either graphically or via CLI

In GUI add detection of the GUI hooks from conflict detection

When we find conflicts, remove them for now. (More advanced logic
may be incoming as I play with it)

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