source: src-qt4/pc-pkgmanager/mainWin.cpp @ 84406a4

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

Enable the basic / advanced view functionality

Save the last view mode, so we startup with it again

Fix a bug changing meta-pkgs, make sure we always refresh to be
positive whats on disk

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