source: src-qt4/pc-pkgmanager/mainWin.cpp @ 5fd031d

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 5fd031d was 5fd031d, checked in by Ken Moore <ken@…>, 13 months ago

Add search functionality to pc-pkgmanager. Still need to setup the keyboard shortcuts (ctrl-F, enter)

  • Property mode set to 100644
File size: 39.6 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  connect(tool_search, SIGNAL( clicked() ), this, SLOT( slotSearchPackages() ) );
43
44  // Setup the action group
45  viewGroup = new QActionGroup(this);
46  viewGroup->addAction(action_Basic);
47  viewGroup->addAction(action_Advanced);
48
49  treeMetaPkgs->setContextMenuPolicy(Qt::CustomContextMenu);
50  connect(treeMetaPkgs, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotMetaRightClick()) );
51
52  QSettings settings("PC-BSD", "PackageManager");
53  QString curMode = settings.value("view/mode").toString();
54  if ( curMode == "Advanced" )
55  {
56     stackedPkgView->setCurrentIndex(1);
57     action_Basic->setChecked(false);
58     action_Advanced->setChecked(true);
59  }
60
61  // If we are running on a chroot, only do advanced mode
62  if ( !wDir.isEmpty() )
63  {
64     stackedPkgView->setCurrentIndex(1);
65     action_Advanced->setChecked(true);
66     menu_View->setEnabled(false);
67     menu_View->setVisible(false);
68  }
69
70  initMetaWidget();
71}
72
73void mainWin::slotViewChanged()
74{
75  QString mode;
76  if ( action_Basic->isChecked() ) {
77    stackedPkgView->setCurrentIndex(0);
78    mode="Basic";
79  } else {
80    mode="Advanced";
81    stackedPkgView->setCurrentIndex(1);
82  }
83
84  // Save the mode as the default at next open
85  QSettings settings("PC-BSD", "PackageManager");
86  settings.setValue("view/mode", mode);
87
88  // Changed view, lets refresh
89  initMetaWidget();
90}
91
92void mainWin::slotRescanPkgsClicked()
93{
94  // Check for pkg updates
95  checkMPKGUpdates();
96}
97
98void mainWin::slotApplyClicked() {
99  // Running in basic mode
100  if ( stackedPkgView->currentIndex() == 0 )
101  {
102     saveMetaPkgs();   
103  } else {
104     // Running in advanced mode
105     applyNGChanges();
106  }
107
108}
109
110void mainWin::slotSearchPackages(){
111  QString pkgSearch = line_search->text();
112  if(pkgSearch.isEmpty()){ return; }
113  qDebug() << "Search for package:" <<pkgSearch;
114  //Get the pointer to the proper treewidget
115  QTreeWidget *TW = treeNGPkgs;
116  if( stackedPkgView->currentIndex() == 0 ){ TW = treeMetaPkgs; }
117  //Make sure the tree widget is not empty
118  if(TW->topLevelItemCount() < 2){ return; }
119  //iterate through the tree widget, starting at the current selection
120  QTreeWidgetItem *CI = TW->currentItem();
121  bool found=false; bool atTop=false;
122  if(CI == 0){ CI = TW->topLevelItem(0); atTop=true; }
123  //Get the starting index (parent and child)
124  QTreeWidgetItem *PI = CI->parent();
125  int startParent=0; int startChild=0;
126  if(PI == 0){ startParent = TW->indexOfTopLevelItem(CI); } //startchild == 0
127  else{ startParent = TW->indexOfTopLevelItem(PI); startChild = PI->indexOfChild(CI) +1; }
128  //Now iterate over the tree, only looking at the actual packages (not categories)
129  found = performSearch(pkgSearch, TW, startParent, startChild);
130  if(!found && !atTop){
131    //Ask whether to restart the search at the top
132    if(QMessageBox::Yes == QMessageBox::question(this,tr("No Search Results"),tr("Do you want to continue the search from the top?"),QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) ){
133      //Restart the search from the top
134      found = performSearch(pkgSearch, TW, 0, 0);
135    }
136  }
137  if(!found){
138    QMessageBox::information(this, tr("No Search Results"), tr("No packages could be found with that search term. Please adjust it and try again.") );
139  }
140  qDebug() << " - Search Finished";
141}
142
143bool mainWin::performSearch(QString pkgSearch, QTreeWidget *TW, int startParent, int startChild){
144  //Iterate over the Tree
145  bool found=false;
146  for(int p=startParent; p<TW->topLevelItemCount(); p++){
147    for(int c=startChild; c<TW->topLevelItem(p)->childCount(); c++){
148      QTreeWidgetItem *CI = TW->topLevelItem(p)->child(c);
149      if(CI->text(0).contains(pkgSearch, Qt::CaseInsensitive)){
150        TW->setCurrentItem(CI);
151        TW->scrollToItem(CI);
152        found=true;
153        break;
154      }
155    }
156    startChild=0; //reset this for the next top level item
157    if(found){ break; }
158  }
159  return found;
160}
161
162void mainWin::checkMPKGUpdates() {
163
164  QString line, tmp, name, pkgname, pkgover, pkgnver;
165  QStringList up, listPkgs;
166  bool haveUpdates = false;
167  int totPkgs=0;
168  buttonRescanPkgs->setEnabled(false);
169  pushUpdatePkgs->setEnabled(false);
170  listViewUpdatesPkgs->clear();
171  groupUpdatesPkgs->setTitle(tr("Checking for updates"));
172
173  QProcess p;
174  if ( wDir.isEmpty() )
175     p.start(QString("pc-updatemanager"), QStringList() << "pkgcheck");
176  else
177     p.start(QString("chroot"), QStringList() << wDir << "pc-updatemanager" << "pkgcheck");
178  while(p.state() == QProcess::Starting || p.state() == QProcess::Running)
179     QCoreApplication::processEvents();
180
181  while (p.canReadLine()) {
182    line = p.readLine().simplified();
183    qDebug() << line;
184    if ( line.indexOf("Upgrading") != 0) {
185       continue;
186    }
187    tmp = line;
188    pkgname = tmp.section(" ", 1, 1);
189    pkgname.replace(":", "");
190    pkgover = tmp.section(" ", 2, 2);
191    pkgnver = tmp.section(" ", 4, 4);
192    QTreeWidgetItem *myItem = new QTreeWidgetItem(QStringList() << pkgname << pkgover << pkgnver);
193    listViewUpdatesPkgs->addTopLevelItem(myItem);
194    haveUpdates = true;
195    totPkgs++;
196  }
197
198  buttonRescanPkgs->setEnabled(true);
199  pushUpdatePkgs->setEnabled(haveUpdates);
200  if ( totPkgs > 0 ) {
201    tabUpdates->setTabText(1, tr("Package Updates (%1)").arg(totPkgs));
202    groupUpdatesPkgs->setTitle(tr("Available updates"));
203  } else {
204    tabUpdates->setTabText(1, tr("Package Updates"));
205    groupUpdatesPkgs->setTitle(tr("No available updates"));
206  }
207 
208}
209
210void mainWin::slotSingleInstance() {
211   this->hide();
212   this->showNormal();
213   this->activateWindow();
214   this->raise();
215}
216
217void mainWin::slotCloseClicked() {
218   close();
219}
220
221void mainWin::slotUpdatePkgsClicked() {
222  dPackages = false;
223  uPackages = false;
224
225  // Init the pkg process
226  prepPkgProcess();
227
228  // Create our runlist of package commands
229  QStringList pCmds;
230
231  if ( wDir.isEmpty() )
232    pCmds << "pc-updatemanager" << "pkgupdate";
233  else
234    pCmds << "chroot" << wDir << "pc-updatemanager" << "pkgupdate";
235
236  // Setup our runList
237  pkgCmdList << pCmds;
238
239  // Start the updating now
240  startPkgProcess();
241
242  textStatus->setText(tr("Starting package updates..."));
243
244}
245
246QString mainWin::getConflictDetailText() {
247
248  QStringList ConList = ConflictList.split(" ");
249  QStringList tmpDeps;
250  QString retText;
251
252  for (int i = 0; i < ConList.size(); ++i) {
253    QProcess p;
254    tmpDeps.clear();
255
256    if ( wDir.isEmpty() )
257      p.start("pkg", QStringList() << "rquery" << "%rn-%rv" << ConList.at(i));
258    else
259      p.start("chroot", QStringList() << wDir << "pkg" "rquery" << "%rn-%rv" << ConList.at(i) );
260
261    if(p.waitForFinished()) {
262      while (p.canReadLine()) {
263        tmpDeps << p.readLine().simplified();
264      }
265    }
266    retText+= ConList.at(i) + " " + tr("required by:") + "\n" + tmpDeps.join(" ");
267  }
268
269  return retText;
270}
271
272void mainWin::prepPkgProcess() {
273  pkgCmdList.clear();
274  textDisplayOut->clear();
275  pkgHasFailed=false;
276}
277
278void mainWin::startPkgProcess() {
279
280  if ( pkgCmdList.isEmpty() )
281    return;
282  if ( pkgCmdList.at(0).at(0).isEmpty() )
283     return; 
284
285  // Get the command name
286  QString cmd;
287  cmd = pkgCmdList.at(0).at(0);
288
289  // Get any optional flags
290  QStringList flags;
291  for (int i = 0; i < pkgCmdList.at(0).size(); ++i) {
292     if ( i == 0 )
293       continue;
294     flags << pkgCmdList.at(0).at(i);
295  } 
296
297  qDebug() << cmd + " " + flags.join(" ");
298 
299  // Setup the first process
300  uProc = new QProcess();
301  QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
302  env.insert("PCFETCHGUI", "YES");
303  uProc->setProcessEnvironment(env);
304  uProc->setProcessChannelMode(QProcess::MergedChannels);
305
306  // Connect the slots
307  connect( uProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotReadPkgOutput()) );
308  connect( uProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotPkgDone()) );
309
310  uProc->start(cmd, flags);
311
312  stackedTop->setCurrentIndex(1);
313
314  progressUpdate->setRange(0, 0 );
315  progressUpdate->setValue(0);
316
317}
318
319void mainWin::slotReadPkgOutput() {
320   QString line, tmp, cur, tot, fname;
321   int curItem, totItem;
322   bool ok;
323
324   while (uProc->canReadLine()) {
325     line = uProc->readLine().simplified();
326     qDebug() << line;
327
328     tmp = line;
329     tmp.truncate(50);
330
331     // Flags we can parse out and not show the user
332
333     // Check if we have crashed into a conflict and ask the user what to do
334     if ( line.indexOf("PKGCONFLICTS: ") == 0 ) {
335        tmp = line; 
336        tmp.replace("PKGCONFLICTS: ", "");
337        ConflictList = tmp;
338        continue;
339     }
340     if ( line.indexOf("PKGREPLY: ") == 0 ) {
341        QString ans;
342        tmp = line; 
343        tmp.replace("PKGREPLY: ", "");
344        QMessageBox msgBox;
345        msgBox.setText(tr("The following packages are causing conflicts with the selected changes and can be automatically removed. Continue?") + "\n" + ConflictList);
346        msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No);
347        msgBox.setDetailedText(getConflictDetailText());
348        msgBox.setDefaultButton(QMessageBox::No);
349        if ( msgBox.exec() == QMessageBox::Yes) {
350          // We will try to fix conflicts
351          ans="yes";
352        } else {
353          // We will fail :(
354          QMessageBox::warning(this, tr("Package Conflicts"),
355          tr("You may need to manually fix the conflicts before trying again."),
356          QMessageBox::Ok,
357          QMessageBox::Ok);
358          ans="no";
359        }
360
361        QFile pkgTrig( tmp );
362        if ( pkgTrig.open( QIODevice::WriteOnly ) ) {
363           QTextStream streamTrig( &pkgTrig );
364           streamTrig << ans;
365           pkgTrig.close();
366        }
367        continue;
368     }
369
370     if ( line.indexOf("FETCH: ") == 0 ) { 
371        progressUpdate->setValue(progressUpdate->value() + 1); 
372        tmp = line; 
373        tmp = tmp.remove(0, tmp.lastIndexOf("/") + 1); 
374        progressUpdate->setRange(0, 0);
375        progressUpdate->setValue(0);
376        curFileText = tr("Downloading: %1").arg(tmp); 
377        textStatus->setText(tr("Downloading: %1").arg(tmp)); 
378        continue;
379     } 
380     if ( line.indexOf("FETCHDONE") == 0 )
381        continue;
382
383     if ( line.indexOf("SIZE: ") == 0 ) {
384          bool ok, ok2;
385          line.replace("SIZE: ", "");
386          line.replace("DOWNLOADED: ", "");
387          line.replace("SPEED: ", "");
388          line.section(" ", 0, 0).toInt(&ok);
389          line.section(" ", 1, 1).toInt(&ok2);
390   
391          if ( ok && ok2 ) {
392            QString unit;
393            int tot = line.section(" ", 0, 0).toInt(&ok);
394            int cur = line.section(" ", 1, 1).toInt(&ok2);
395            QString percent = QString::number( (float)(cur * 100)/tot );
396            QString speed = line.section(" ", 2, 3);
397
398            // Get the MB downloaded / total
399            if ( tot > 2048 ) {
400              unit="MB";
401              tot = tot / 1024;
402              cur = cur / 1024;
403            } else {
404              unit="KB";
405            }
406
407            QString ProgressString=QString("(%1" + unit + " of %2" + unit + " at %3)").arg(cur).arg(tot).arg(speed);
408            progressUpdate->setRange(0, tot);
409            progressUpdate->setValue(cur);
410            textStatus->setText(curFileText + " " + ProgressString); 
411         }
412         continue;
413     }
414
415
416     // Now show output on GUI
417     textDisplayOut->insertPlainText(line + "\n");
418     textDisplayOut->moveCursor(QTextCursor::End);
419
420
421     // Any other flags to look for?
422     /////////////////////////////////////////////////////
423     if ( line.indexOf("to be downloaded") != -1 ) {
424       textStatus->setText(tr("Downloading packages..."));
425       curUpdate = 0;
426       progressUpdate->setValue(0);
427       continue;
428     }
429     if ( line.indexOf("Checking integrity") == 0 ) {
430       textStatus->setText(line);
431       uPackages = true;
432       dPackages = false;
433       curUpdate = 0;
434       progressUpdate->setValue(0);
435       progressUpdate->setRange(0, 0);
436       progressUpdate->setValue(0);
437       continue;
438     }
439     
440     if ( uPackages ) {
441       if ( line.indexOf("[") == 0 ) {
442         tmp=line.section("]", 1, 1);
443         textStatus->setText(tmp);
444         tmp=line.section("/", 0, 0).replace("[", "");
445         tmp.toInt(&ok);
446         if (ok)  {
447           curItem=tmp.toInt(&ok);
448           tmp=line.section("/", 1, 1).section("]", 0, 0);
449           tmp.toInt(&ok);
450           if (ok)  {
451             totItem=tmp.toInt(&ok);
452             progressUpdate->setRange(0, totItem);
453             progressUpdate->setValue(curItem);
454           }
455
456         }
457       }
458       continue;
459     }
460
461   } // end of while
462}
463
464void mainWin::slotPkgDone() {
465
466  if ( uProc->exitCode() != 0 )
467    pkgHasFailed=true;
468
469  // Run the next command on the stack if necessary
470  if (  pkgCmdList.size() > 1 ) {
471        pkgCmdList.removeAt(0); 
472        startPkgProcess();     
473        return;
474  }
475
476  // Nothing left to run! Lets wrap up
477  QFile sysTrig( SYSTRIGGER );
478  if ( sysTrig.open( QIODevice::WriteOnly ) ) {
479    QTextStream streamTrig( &sysTrig );
480     streamTrig << "INSTALLFINISHED: ";
481  }
482
483  if ( pkgHasFailed ) {
484    QFile file( "/tmp/pkg-output.log" );
485    if ( file.open( QIODevice::WriteOnly ) ) {
486       QTextStream stream( &file );
487       stream << textDisplayOut->toPlainText();
488       file.close();
489    }
490    QMessageBox::warning(this, tr("Failed!"), tr("The package commands failed. A copy of the output was saved to /tmp/pkg-output.log"));
491  } else
492    QMessageBox::warning(this, tr("Finished!"), tr("Package changes complete!" ));
493
494  // Clear out the old commands
495  pkgCmdList.clear();
496
497  // Switch back to our main display
498  stackedTop->setCurrentIndex(0);
499 
500  // Re-init the meta-widget
501  initMetaWidget();
502
503}
504
505/*****************************************
506Code for package stuff
507******************************************/
508
509void mainWin::initMetaWidget()
510{
511  qDebug() << "Starting metaWidget...";
512  groupInfo->setVisible(false);
513
514  // Running in basic mode
515  if ( stackedPkgView->currentIndex() == 0 )
516  {
517    populateMetaPkgs();
518    // Connect our slots
519  } else {
520    // Running in advanced mode
521    populateNGPkgs();
522  }
523}
524
525void mainWin::populateNGPkgs()
526{
527  pushPkgApply->setEnabled(false);
528  treeNGPkgs->clear();
529  tmpPkgList.clear();
530  new QTreeWidgetItem(treeNGPkgs, QStringList() << tr("Loading... Please wait...") );
531
532  if ( ! pkgList.isEmpty() ) {
533        disconnect(treeNGPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), 0, 0);
534        disconnect(treeNGPkgs, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), 0, 0);
535  }
536  pkgList.clear();
537  selPkgList.clear();
538
539  // Start the process to get meta-pkg info
540  getNGProc = new QProcess();
541  qDebug() << "Searching for pkgs...";
542  connect( getNGProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotGetNGPackageDataOutput()) );
543  connect( getNGProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotGetNGInstalledPkgs()) );
544  getNGProc->setProcessChannelMode(QProcess::MergedChannels);
545  if ( wDir.isEmpty() )
546    getNGProc->start(QString("pkg"), QStringList() << "rquery" << "-a" << "%o:::%n-%v:::%c:::%sh:::%m:::%w");
547  else
548    getNGProc->start(QString("chroot"), QStringList() << wDir << "pkg" << "rquery" << "-a" << "%o:::%n-%v:::%c:::%sh:::%m:::%w");
549
550}
551
552void mainWin::slotGetNGPackageDataOutput()
553{
554   while (getNGProc->canReadLine())
555     tmpPkgList << getNGProc->readLine().simplified();
556}
557
558void mainWin::slotGetNGInstalledDataOutput()
559{
560   while (getNGProc->canReadLine())
561     pkgList << getNGProc->readLine().simplified();
562}
563
564void mainWin::slotGetNGInstalledPkgs() {
565
566  qDebug() << "Building dependancy lists...";
567  QProcess p;
568  pkgDepList.clear();
569  if ( wDir.isEmpty() )
570    p.start("pkg", QStringList() << "rquery" << "-a" << "%n-%v:::%dn-%dv");
571  else
572    p.start("chroot", QStringList() << wDir << "pkg" << "rquery" << "-a" << "%n-%v:::%dn-%dv" );
573  while(p.state() == QProcess::Starting || p.state() == QProcess::Running) {
574      p.waitForFinished(200);
575      QCoreApplication::processEvents();
576  }
577  while (p.canReadLine()) {
578    pkgDepList << p.readLine().simplified();
579  }
580
581  getNGProc = new QProcess();
582  qDebug() << "Searching for installed pkgs...";
583  connect( getNGProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotGetNGInstalledDataOutput()) );
584  connect( getNGProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishLoadingNGPkgs()) );
585  getNGProc->setProcessChannelMode(QProcess::MergedChannels);
586  if ( wDir.isEmpty() )
587    getNGProc->start(QString("pkg"), QStringList() << "info" << "-aq" );
588  else
589    getNGProc->start(QString("chroot"), QStringList() << wDir << "pkg" << "info" << "-aq");
590
591}
592
593void mainWin::slotFinishLoadingNGPkgs()
594{
595  treeNGPkgs->clear();
596
597  addNGItems();
598
599  pushPkgApply->setEnabled(false);
600
601  connect(treeNGPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotEnableApply()));
602  connect(treeNGPkgs, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotNGItemChanged()));
603
604  // Now we can look for updates safely
605  slotRescanPkgsClicked();
606}
607
608void mainWin::slotNGItemChanged()
609{
610  if ( ! treeNGPkgs->currentItem() ) {
611     groupInfo->setVisible(false);
612     return;
613  }
614  QString desc, size, maint, weburl;
615
616  QTreeWidgetItem *cItem = treeNGPkgs->currentItem();
617  QString pName = cItem->text(0).section("(", 1, 1).section(")", 0, 0);
618  if ( pName.isEmpty() ) {
619     groupInfo->setVisible(false);
620     return;
621  }
622  qDebug() << "Checking: " + pName;
623
624  QRegExp rx("*:::" + pName + ":::*");
625  rx.setPatternSyntax(QRegExp::Wildcard);
626  int pAt = tmpPkgList.indexOf(rx);
627  if (pAt == -1 ) {
628     qDebug() << "Unable to find package: " + pName;
629     groupInfo->setVisible(false);
630     return;
631  }
632
633  desc = tmpPkgList.at(pAt).section(":::", 2,2);
634  size = tmpPkgList.at(pAt).section(":::", 3,3);
635  maint = tmpPkgList.at(pAt).section(":::", 4,4);
636  weburl = tmpPkgList.at(pAt).section(":::", 5,5);
637  labelPkgNameVer->setText(pName);
638  labelSize->setText(size);
639  labelWeb->setText(weburl);
640  textDesc->setText(desc);
641  textOptions->clear();
642
643  QCoreApplication::processEvents();
644
645  // Display the depends
646  QString depTxt;
647  QRegExp rxd( pName + ":::*");
648  rxd.setPatternSyntax(QRegExp::Wildcard);
649  QStringList aDeps = pkgDepList.filter(rxd);
650  for ( int r=0; r < aDeps.size(); ++r) {
651      QString dName = aDeps.at(r).section(":::", 1, 1);
652      // Is this package installed?
653      if ( pkgList.indexOf(dName) != -1 )
654         depTxt+= dName + " (Installed)\n";
655      else
656         depTxt+= dName + "\n";
657  }
658
659  textDeps->setText(depTxt);
660
661  groupInfo->setVisible(true);
662
663  getNGInfo = new QProcess();
664  qDebug() << "Getting Info for " + pName;
665  connect( getNGInfo, SIGNAL(readyReadStandardOutput()), this, SLOT(slotNGReadInfo()) );
666  getNGInfo->setProcessChannelMode(QProcess::MergedChannels);
667  if ( wDir.isEmpty() )
668    getNGInfo->start(QString("pkg"), QStringList() << "rquery" << "%Ok=%Ov" << pName );
669  else
670    getNGInfo->start(QString("chroot"), QStringList() << wDir << "pkg" << "rquery" << "%Ok=%Ov" << pName);
671}
672
673void mainWin::slotNGReadInfo()
674{
675  while (getNGInfo->canReadLine())
676     textOptions->append(getNGInfo->readLine().simplified() );
677
678  textOptions->moveCursor(QTextCursor::Start);
679}
680
681void mainWin::slotEnableApply()
682{
683  pushPkgApply->setEnabled(true);
684}
685
686void mainWin::addNGItems()
687{
688   QString curCat, cat, name, pkgname, desc, size, maint, weburl;
689
690   // We like to add alphabetically
691   tmpPkgList.sort();
692
693   QTreeWidgetItem *catItem = new QTreeWidgetItem;
694
695   // Lets start adding packages to the tree widget
696   for (int i = 0; i < tmpPkgList.size(); ++i) {
697        name = cat = tmpPkgList.at(i).section(":::", 0,0);
698        cat=cat.section("/", 0, 0);
699        name=name.section("/", 1, 1);
700        pkgname = tmpPkgList.at(i).section(":::", 1,1);
701        desc = tmpPkgList.at(i).section(":::", 2,2);
702        size = tmpPkgList.at(i).section(":::", 3,3);
703        maint = tmpPkgList.at(i).section(":::", 4,4);
704        weburl = tmpPkgList.at(i).section(":::", 5,5);
705
706        // Check if we need to add a top-level category
707        if ( cat != curCat )
708        {
709           qDebug() << "Adding cat: " + cat;
710           catItem = new QTreeWidgetItem(QStringList() << cat);
711           treeNGPkgs->addTopLevelItem(catItem);
712           curCat = cat;
713        }
714 
715        // Now lets create the item and attach to the category
716        QTreeWidgetItem *pkgItem = new QTreeWidgetItem();
717        pkgItem->setText(0, name + " (" + pkgname + ") - " + size );
718        pkgItem->setToolTip(0, desc);
719
720        if ( pkgList.indexOf(pkgname) != -1 ) {
721          pkgItem->setCheckState(0, Qt::Checked);
722          selPkgList << pkgname;
723        } else
724          pkgItem->setCheckState(0, Qt::Unchecked);
725 
726        catItem->addChild(pkgItem);
727   }
728}
729
730// Lets prompt user, and do it!
731void mainWin::applyNGChanges()
732{
733   QString tmp;
734   QStringList curPkgChecked;
735   QStringList newPkgs;
736   QStringList rmPkgs;
737
738   QTreeWidgetItemIterator it(treeNGPkgs);
739   while (*it) {
740         if ((*it)->checkState(0) == Qt::Checked) {
741           tmp = (*it)->text(0).section("(", 1, 1).section(")", 0, 0);
742           curPkgChecked << tmp;
743           if (pkgList.indexOf(tmp) == -1 ) 
744              newPkgs << tmp;
745         }
746         ++it;
747   }
748
749   for ( int i=0; i < pkgList.size(); ++i)
750      // Has this package been unchecked?
751      if (curPkgChecked.indexOf(pkgList.at(i)) == -1 )  {
752         // Make sure this is a package in the repo
753         // This filters out any custom packages the user may have loaded which may not exist in our repo
754         QRegExp rx("*" + pkgList.at(i) + "*");
755         rx.setPatternSyntax(QRegExp::Wildcard);
756         if ( tmpPkgList.indexOf(rx) != -1 )
757           rmPkgs << pkgList.at(i);
758      }
759
760   if ( rmPkgs.isEmpty() && newPkgs.isEmpty() ) {
761      QMessageBox::warning(this, tr("No changes"),
762        tr("No changes to make!"),
763        QMessageBox::Ok,
764        QMessageBox::Ok);
765      return;
766   }
767
768   qDebug() << "Added packages" << newPkgs;
769   qDebug() << "Removed packages" << rmPkgs;
770   pkgRemoveList = rmPkgs;
771   pkgAddList = newPkgs;
772
773   QString confirmText;
774
775   // Lets start creating our confirmation text
776   if ( ! rmPkgs.isEmpty() ) {
777      confirmText+=tr("The following packages will be removed:") + "\n"; 
778      confirmText+= "------------------------------------------\n";
779      confirmText+=rmPkgs.join("\n"); 
780      confirmText+= "\n\n" + tr("The following packages that require the above packages will also removed:") + "\n"; 
781      confirmText+= "------------------------------------------\n";
782      for ( int i=0; i < rmPkgs.size(); ++i) {
783       
784         // Get rdeps for this pkg
785         qDebug() << "Building reverse dependancy lists...";
786         pkgRDepList.clear();
787         QProcess p;
788         if ( wDir.isEmpty() )
789           p.start("pkg", QStringList() << "rquery" << "%n-%v:::%rn-%rv" << rmPkgs.at(i));
790         else
791           p.start("chroot", QStringList() << wDir << "pkg" << "rquery" << "%n-%v:::%rn-%rv" << rmPkgs.at(i) );
792         while(p.state() == QProcess::Starting || p.state() == QProcess::Running) {
793           p.waitForFinished(200);
794           QCoreApplication::processEvents();
795         }
796         while (p.canReadLine()) {
797           pkgRDepList << p.readLine().simplified();
798         }
799
800         QRegExp rx(rmPkgs.at(i) + ":::*");
801         rx.setPatternSyntax(QRegExp::Wildcard);
802         QStringList rDeps = pkgRDepList.filter(rx);
803         for ( int r=0; r < rDeps.size(); ++r) {
804             QString pName = rDeps.at(r).section(":::", 1, 1); 
805             // Is this package installed?
806             if ( pkgList.indexOf(pName) != -1 )
807               confirmText+= pName + " ";
808         }
809      }
810   }
811
812   if ( ! newPkgs.isEmpty() ) {
813      if ( ! rmPkgs.isEmpty() )
814        confirmText+= "\n\n";
815      confirmText+=tr("The following packages will be installed:") + "\n"; 
816      confirmText+= "------------------------------------------\n";
817      confirmText+=newPkgs.join("\n"); 
818      confirmText+= "\n\n" + tr("The following dependances will also be installed:") + "\n"; 
819      confirmText+= "------------------------------------------\n";
820      for ( int i=0; i < newPkgs.size(); ++i) {
821         QRegExp rx(newPkgs.at(i) + ":::*");
822         rx.setPatternSyntax(QRegExp::Wildcard);
823         QStringList aDeps = pkgDepList.filter(rx);
824         for ( int r=0; r < aDeps.size(); ++r) {
825             QString pName = aDeps.at(r).section(":::", 1, 1); 
826             // Is this package installed?
827             if ( pkgList.indexOf(pName) == -1 )
828               confirmText+= pName + " ";
829         }
830      }
831   }
832
833   // Launch our AddPartitionDialog to add a new device
834   askUserConfirm = new dialogConfirm();
835   connect(askUserConfirm, SIGNAL(ok()),this, SLOT(slotStartNGChanges()) );
836   askUserConfirm->programInit(tr("Confirm package changes"));
837   askUserConfirm->setInfoText(QString(confirmText));
838   askUserConfirm->exec();
839
840}
841
842
843// Time to start doing our NG changes!
844void mainWin::slotStartNGChanges()
845{
846  // Init the pkg process
847  prepPkgProcess();
848
849  // Create our runlist of package commands
850  QStringList pCmds;
851 
852  if ( ! pkgRemoveList.isEmpty() ) {
853    if ( wDir.isEmpty() )
854      pCmds << "pkg" << "delete" << "-R" << "-y" << pkgRemoveList.join(" ");
855    else
856      pCmds << "chroot" << wDir << "pkg" << "delete" << "-R" << "-y" << pkgRemoveList.join(" ");
857    pkgCmdList << pCmds;
858  }
859         
860  pCmds.clear();
861
862  if ( ! pkgAddList.isEmpty() ) {
863    if ( wDir.isEmpty() )
864      pCmds << "pc-pkg" << "install" << "-y" << pkgAddList.join(" ");
865    else
866      pCmds << "chroot" << wDir << "pc-pkg" << "install" << "-y" << pkgAddList.join(" ");
867    pkgCmdList << pCmds;
868  }
869
870  // Lets kick it off now
871  startPkgProcess();
872}
873
874// Display found meta-pkg data
875void mainWin::populateMetaPkgs()
876{
877  pushPkgApply->setEnabled(false);
878  treeMetaPkgs->clear();
879  tmpMetaPkgList.clear();
880  new QTreeWidgetItem(treeMetaPkgs, QStringList() << tr("Loading... Please wait...") );
881
882  if ( ! metaPkgList.isEmpty() )
883        disconnect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), 0, 0);
884  metaPkgList.clear();
885
886  // Start the process to get meta-pkg info
887  getMetaProc = new QProcess();
888  qDebug() << "Searching for meta-pkgs...";
889  connect( getMetaProc, SIGNAL(readyReadStandardOutput()), this, SLOT(slotGetPackageDataOutput()) );
890  connect( getMetaProc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotFinishLoadingMetaPkgs()) );
891  getMetaProc->setProcessChannelMode(QProcess::MergedChannels);
892  getMetaProc->start(QString("pc-metapkgmanager"), QStringList() << "list");
893
894}
895
896// Display found meta-pkg data
897void mainWin::slotFinishLoadingMetaPkgs()
898{
899
900  // Populate the metaPkgList
901  parseTmpMetaList();
902
903  treeMetaPkgs->clear();
904
905  addTreeItems(QString()); 
906
907  pushPkgApply->setEnabled(false);
908
909  connect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotDeskPkgsChanged(QTreeWidgetItem *, int)));
910
911  // Now we can look for updates safely
912  slotRescanPkgsClicked();
913}
914
915void mainWin::addTreeItems(QString parent)
916{
917  for (int z=0; z < metaPkgList.count(); ++z) {
918    if ( metaPkgList.at(z).at(3) != parent )
919      continue;
920
921    // Hide the "base-system" package, since we are installing it anyway
922    if (metaPkgList.at(z).at(0) == "base-system" )
923      return;
924
925    QTreeWidgetItem *deskItem = new QTreeWidgetItem(QStringList() << metaPkgList.at(z).at(0) );
926    deskItem->setIcon(0, QIcon(metaPkgList.at(z).at(2)));
927    deskItem->setToolTip(0, metaPkgList.at(z).at(1));
928    deskItem->setCheckState(0, Qt::Unchecked);
929
930    if ( metaPkgList.at(z).at(5) == "YES" )
931      deskItem->setCheckState(0, Qt::Checked);
932
933    if ( parent.isEmpty() ) {
934      treeMetaPkgs->addTopLevelItem(deskItem);
935    } else {
936      // Locate the parent to attach to
937      QTreeWidgetItemIterator it(treeMetaPkgs);
938      while (*it) {
939        if ((*it)->text(0) == parent ) {
940          (*it)->addChild(deskItem);
941          if ( metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked)
942            (*it)->setCheckState(0, Qt::PartiallyChecked);
943          if ( metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked)
944            (*it)->setCheckState(0, Qt::PartiallyChecked);
945          break;
946        }
947        it++;
948      }
949    }
950
951    // Now look for any possible children
952    addTreeItems(metaPkgList.at(z).at(0));   
953  }
954
955}
956
957// Check if a meta-pkg is installed
958bool mainWin::isMetaPkgInstalled(QString mPkg)
959{
960  QString tmp;
961  QProcess pcmp;
962  pcmp.start(QString("pc-metapkgmanager"), QStringList() << chrootArg1 << chrootArg2 << "status" << mPkg);
963  while ( pcmp.state() != QProcess::NotRunning ) {
964     pcmp.waitForFinished(50);
965     QCoreApplication::processEvents();
966  }
967
968  while (pcmp.canReadLine()) {
969     tmp = pcmp.readLine().simplified();
970     if ( tmp.indexOf("is installed") != -1 )
971     return true;
972  }
973
974  return false;
975}
976
977// Function which checks for our GUI package schema data
978void mainWin::slotGetPackageDataOutput()
979{
980  while (getMetaProc->canReadLine())
981        tmpMetaPkgList << getMetaProc->readLine().simplified();
982}
983
984// Parse the pc-metapkg saved output
985void mainWin::parseTmpMetaList()
986{
987  QString tmp, mName, mDesc, mIcon, mParent, mDesktop, mInstalled, mPkgFileList;
988  QStringList package;
989
990  for ( int i = 0 ; i < tmpMetaPkgList.size(); i++ )
991  {
992        QApplication::processEvents();
993
994        tmp = tmpMetaPkgList.at(i);
995
996        if ( tmp.indexOf("Meta Package: ") == 0) {
997                mName = tmp.replace("Meta Package: ", "");
998                continue;
999        }
1000        if ( tmp.indexOf("Description: ") == 0) {
1001                mDesc = tmp.replace("Description: ", "");
1002                continue;
1003        }
1004        if ( tmp.indexOf("Icon: ") == 0) {
1005                mIcon = tmp.replace("Icon: ", "");
1006                mPkgFileList = mIcon;
1007                mPkgFileList.replace("pkg-icon.png", "pkg-list");
1008                continue;
1009        }
1010        if ( tmp.indexOf("Parent: ") == 0) {
1011                mParent = tmp.replace("Parent: ", "");
1012                continue;
1013        }
1014        if ( tmp.indexOf("Desktop: ") == 0) {
1015                mDesktop = tmp.replace("Desktop: ", "");
1016                continue;
1017        }
1018
1019        // This is an empty category
1020        if ( tmp.indexOf("Category Entry") == 0) {
1021                // Now add this category to the string list
1022                package.clear();
1023                qDebug() << "Found Package" << mName << mDesc << mIcon << mParent << mDesktop;
1024                mInstalled = "CATEGORY";
1025                package << mName << mDesc << mIcon << mParent << mDesktop << mInstalled;
1026                metaPkgList.append(package);
1027                mName=""; mDesc=""; mIcon=""; mParent=""; mDesktop=""; mInstalled=""; mPkgFileList="";
1028        }
1029
1030        // We have a Meta-Pkg
1031        if ( tmp.indexOf("Required Packages:") == 0) {
1032                // Now add this meta-pkg to the string list
1033                package.clear();
1034                qDebug() << "Found Package" << mName << mDesc << mIcon << mParent << mDesktop << mPkgFileList;
1035
1036                if ( isMetaPkgInstalled(mName) )
1037                        mInstalled = "YES";
1038                else
1039                        mInstalled = "NO";
1040
1041                package << mName << mDesc << mIcon << mParent << mDesktop << mInstalled << mPkgFileList;
1042                metaPkgList.append(package);
1043                mName=""; mDesc=""; mIcon=""; mParent=""; mDesktop=""; mInstalled=""; mPkgFileList="";
1044        }
1045
1046    }
1047
1048}
1049
1050void mainWin::saveMetaPkgs()
1051{
1052        if ( ! haveMetaPkgChanges() )
1053                return;
1054
1055        addPkgs = getAddPkgs();
1056        delPkgs = getDelPkgs(); 
1057
1058        startMetaChanges();
1059
1060}
1061
1062void mainWin::startMetaChanges()
1063{
1064
1065  // Init the pkg process
1066  prepPkgProcess();
1067  // Create our runlist of package commands
1068  QStringList pCmds;
1069
1070  if ( ! delPkgs.isEmpty() ) {
1071    if ( wDir.isEmpty() )
1072      pCmds << "pc-metapkgmanager" << "del" << delPkgs;
1073    else 
1074      pCmds << "chroot" << wDir << "pc-metapkgmanager" << "del" << delPkgs;
1075    pkgCmdList << pCmds;
1076  }
1077 
1078  pCmds.clear();
1079
1080  if ( ! addPkgs.isEmpty() ) {
1081    if ( wDir.isEmpty() )
1082      pCmds << "pc-metapkgmanager" << "add" << addPkgs;
1083    else 
1084      pCmds << "chroot" << wDir << "pc-metapkgmanager" << "add" << addPkgs;
1085    pkgCmdList << pCmds;
1086  }
1087
1088  // Lets kick it off now
1089  startPkgProcess();
1090}
1091
1092bool mainWin::haveAMetaDesktop()
1093{
1094        // If running in a chroot we can skip this check
1095        if ( ! chrootArg1.isEmpty() )
1096          return true;
1097       
1098        QTreeWidgetItemIterator it(treeMetaPkgs);
1099        while (*it) {
1100         if ( ((*it)->checkState(0) == Qt::Checked) || ((*it)->checkState(0) == Qt::PartiallyChecked) )
1101           for (int z=0; z < metaPkgList.count(); ++z)
1102             if ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(4) == "YES" )
1103                return true;
1104         ++it;
1105        }
1106
1107        QMessageBox::warning(this, tr("No Desktop"),
1108          tr("No desktops have been selected! Please choose at least one desktop before saving."),
1109          QMessageBox::Ok,
1110          QMessageBox::Ok);
1111
1112        return false;
1113}
1114
1115bool mainWin::haveMetaPkgChanges()
1116{
1117        QTreeWidgetItemIterator it(treeMetaPkgs);
1118        while (*it) {
1119          for (int z=0; z < metaPkgList.count(); ++z)
1120            // See if any packages status have changed
1121            if ( ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked ) \
1122              || ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::PartiallyChecked ) \
1123              || ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked ) )
1124                return true;
1125         ++it;
1126        }
1127
1128        return false;
1129}
1130
1131QString mainWin::getAddPkgs()
1132{
1133        QString tmp;
1134        QTreeWidgetItemIterator it(treeMetaPkgs);
1135        while (*it) {
1136          for (int z=0; z < metaPkgList.count(); ++z)
1137            // See if any packages status have changed
1138            if ( ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::Checked ) || \
1139                 ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "NO" && (*it)->checkState(0) == Qt::PartiallyChecked ) )
1140                if ( tmp.isEmpty() )
1141                        tmp = (*it)->text(0);
1142                else
1143                        tmp = tmp + "," + (*it)->text(0);
1144         ++it;
1145        }
1146
1147        return tmp;
1148}
1149
1150QString mainWin::getDelPkgs()
1151{
1152        QString tmp;
1153        QTreeWidgetItemIterator it(treeMetaPkgs);
1154        while (*it) {
1155          for (int z=0; z < metaPkgList.count(); ++z)
1156            // See if any packages status have changed
1157            if ( (*it)->text(0) == metaPkgList.at(z).at(0) && metaPkgList.at(z).at(5) == "YES" && (*it)->checkState(0) == Qt::Unchecked )
1158                if ( tmp.isEmpty() )
1159                        tmp = (*it)->text(0);
1160                else
1161                        tmp = tmp + "," + (*it)->text(0);
1162         ++it;
1163        }
1164
1165        return tmp;
1166}
1167
1168
1169// Time to save meta-pkgs
1170void mainWin::slotApplyMetaChanges() {
1171    saveMetaPkgs();
1172}
1173
1174
1175
1176// The User changed the tree widget checked / unchecked stuff sanity check
1177void mainWin::slotDeskPkgsChanged(QTreeWidgetItem *aItem, int __unused)
1178{
1179        if (!aItem)
1180          return;
1181
1182        disconnect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), 0, 0);
1183
1184        if (aItem->childCount() == 0) {
1185                if (aItem->checkState(0) == Qt::Checked && aItem->parent() )
1186                        if ( allChildrenPkgsChecked(aItem->parent()->text(0)))
1187                                aItem->parent()->setCheckState(0, Qt::Checked); 
1188                        else
1189                                aItem->parent()->setCheckState(0, Qt::PartiallyChecked);       
1190                if (aItem->checkState(0) == Qt::Unchecked && aItem->parent() )
1191                        if ( ! allChildrenPkgsUnchecked(aItem->parent()->text(0)))
1192                                aItem->parent()->setCheckState(0, Qt::PartiallyChecked);       
1193
1194
1195        } else {
1196                if (aItem->checkState(0) == Qt::Checked )
1197                        checkAllChildrenPkgs(aItem->text(0));
1198                else
1199                        uncheckAllChildrenPkgs(aItem->text(0));
1200        }
1201       
1202
1203    connect(treeMetaPkgs, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotDeskPkgsChanged(QTreeWidgetItem *, int)));
1204
1205        if ( haveMetaPkgChanges() )
1206                pushPkgApply->setEnabled(true);
1207        else
1208                pushPkgApply->setEnabled(false);
1209}
1210
1211// Check the "parent" app to see if all its children are checked or not
1212bool mainWin::allChildrenPkgsChecked(QString parent)
1213{
1214        QTreeWidgetItemIterator it(treeMetaPkgs);
1215        while (*it) {
1216         if ((*it)->text(0) == parent ) {
1217           if ( (*it)->childCount() <= 0)
1218             return true;
1219
1220           for ( int i = 0; i < (*it)->childCount() ; ++i) {
1221             if ( ! allChildrenPkgsChecked((*it)->child(i)->text(0)))
1222               return false;
1223
1224             if ((*it)->child(i)->checkState(0) != Qt::Checked ) 
1225               return false;
1226           }
1227         }
1228         ++it;
1229        }
1230        return true;
1231}
1232
1233// Check the "parent" app to see if all its children are unchecked or not
1234bool mainWin::allChildrenPkgsUnchecked(QString parent)
1235{
1236        QTreeWidgetItemIterator it(treeMetaPkgs);
1237        while (*it) {
1238         if ((*it)->text(0) == parent ) {
1239           if ( (*it)->childCount() <= 0)
1240             return true;
1241
1242           for ( int i = 0; i < (*it)->childCount() ; ++i) {
1243             if ( ! allChildrenPkgsUnchecked((*it)->child(i)->text(0)))
1244               return false;
1245
1246             if ((*it)->child(i)->checkState(0) != Qt::Unchecked ) 
1247               return false;
1248           }
1249         }
1250         ++it;
1251        }
1252        return true;
1253}
1254
1255// Check all children of parent
1256void mainWin::checkAllChildrenPkgs(QString parent)
1257{
1258        QTreeWidgetItemIterator it(treeMetaPkgs);
1259        while (*it) {
1260         if (! (*it)->parent()) {
1261           ++it;
1262           continue;
1263         } 
1264
1265         // Lets walk the tree see what pops up
1266         bool pFound=false;
1267         QTreeWidgetItem *itP = (*it)->parent();
1268         do {
1269           pFound=false;
1270           if (itP->text(0) == parent) {
1271             (*it)->setCheckState(0, Qt::Checked);
1272             break;
1273           }
1274           if ( itP->parent() ) {
1275             itP = itP->parent();
1276             pFound=true;
1277           }
1278         } while (pFound);
1279
1280         ++it;
1281       }
1282}
1283
1284// UnCheck all children of parent
1285void mainWin::uncheckAllChildrenPkgs(QString parent)
1286{
1287        QTreeWidgetItemIterator it(treeMetaPkgs);
1288        while (*it) {
1289         if (! (*it)->parent()) {
1290           ++it;
1291           continue;
1292         } 
1293
1294         // Lets walk the tree see what pops up
1295         bool pFound=false;
1296         QTreeWidgetItem *itP = (*it)->parent();
1297         do {
1298           pFound=false;
1299           if (itP->text(0) == parent) {
1300             (*it)->setCheckState(0, Qt::Unchecked);
1301             break;
1302           }
1303           if ( itP->parent() ) {
1304             itP = itP->parent();
1305             pFound=true;
1306           }
1307         } while (pFound);
1308
1309         ++it;
1310       }
1311}
1312
1313void mainWin::slotMetaRightClick()
1314{
1315        QTreeWidgetItemIterator it(treeMetaPkgs);
1316        while (*it) {
1317          for (int z=0; z < metaPkgList.count(); ++z) {
1318            if ( (*it)->isSelected() && (*it)->text(0) == metaPkgList.at(z).at(0) ) {
1319              if (metaPkgList.at(z).at(5) == "CATEGORY")
1320                return;
1321              popup = new QMenu;
1322              popup->setTitle((*it)->text(0));
1323              popup->addAction(tr("View Packages"), this, SLOT(slotMetaViewPkgs()));
1324              popup->exec( QCursor::pos() );
1325            }
1326          }
1327         ++it;
1328        }
1329}
1330
1331void mainWin::slotMetaViewPkgs()
1332{
1333        QStringList packageList;
1334        QTreeWidgetItemIterator it(treeMetaPkgs);
1335        while (*it) {
1336          for (int z=0; z < metaPkgList.count(); ++z) {
1337            if ( (*it)->isSelected() && (*it)->text(0) == metaPkgList.at(z).at(0) ) {
1338 
1339                QFile pList(metaPkgList.at(z).at(6));
1340                if ( ! pList.exists() )
1341                  return;
1342               
1343                if ( ! pList.open(QIODevice::ReadOnly | QIODevice::Text))
1344                  return;
1345
1346                while ( !pList.atEnd() )
1347                  packageList << pList.readLine().simplified();
1348
1349                pList.close();
1350                packageList.sort();
1351                       
1352                dIB = new dialogInfo();
1353                dIB->programInit(tr("Package Listing for:") + " " + (*it)->text(0));
1354                dIB->setInfoText(packageList.join("\n"));
1355                dIB->show();
1356            }
1357          }
1358         ++it;
1359        }
1360}
1361
1362QString mainWin::getLineFromCommandOutput( QString cmd )
1363{
1364        FILE *file = popen(cmd.toLatin1(),"r");
1365 
1366        char buffer[100];
1367 
1368        QString line = "";
1369        char firstChar;
1370
1371        if ((firstChar = fgetc(file)) != -1){
1372                line += firstChar;
1373                line += fgets(buffer,100,file);
1374        }
1375        pclose(file);
1376        return line.simplified();
1377}
Note: See TracBrowser for help on using the repository browser.