source: src-qt4/pc-pkgmanager/mainWin.cpp @ 83ebbb5

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

Change how we call the conflict message box, add a placeholder for additional text about the conflicting packages, so we can make a better choice as to remove it or not

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