SelectableImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 //#include "zypp/base/Logger.h"
00014 
00015 #include "zypp/ui/SelectableImpl.h"
00016 
00017 using std::endl;
00018 
00020 namespace zypp
00021 { 
00022 
00023   namespace ui
00024   { 
00025 
00027     //
00028     //  CLASS NAME : StatusHelper
00029     //
00032     struct StatusHelper
00033     {
00034       StatusHelper( const Selectable::Impl & impl )
00035       : _impl( impl )
00036       , inst( impl.installedObj() )
00037       , cand( impl.candidateObj() )
00038       {}
00039 
00040       typedef Selectable::Impl::availableItem_const_iterator availableItem_const_iterator;
00041 
00042       //
00043       // Queries
00044       //
00045       bool hasInstalled() const
00046       { return inst; }
00047 
00048       bool hasCandidate() const
00049       { return cand; }
00050 
00051       bool hasInstalledOnly() const
00052       { return inst && !cand; }
00053 
00054       bool hasCandidateOnly() const
00055       { return cand && !inst; }
00056 
00057       bool hasBoth() const
00058       { return inst && cand; }
00059 
00060       //
00061       // ResStatus manip
00062       //
00063       void resetTransactingCandidates() const
00064       {
00065         for ( availableItem_const_iterator it = _impl.availableBegin();
00066               it != _impl.availableEnd(); ++it )
00067           {
00068             (*it).status().setTransact( false, ResStatus::USER );
00069           }
00070       }
00071       void unlockCandidates() const
00072       {
00073         for ( availableItem_const_iterator it = _impl.availableBegin();
00074               it != _impl.availableEnd(); ++it )
00075           {
00076             (*it).status().setTransact( false, ResStatus::USER );
00077             (*it).status().setLock( false, ResStatus::USER );
00078           }
00079       }
00080       void lockCandidates() const
00081       {
00082         for ( availableItem_const_iterator it = _impl.availableBegin();
00083               it != _impl.availableEnd(); ++it )
00084           {
00085             (*it).status().setTransact( false, ResStatus::USER );
00086             (*it).status().setLock( true, ResStatus::USER );
00087           }
00088       }
00089 
00090       bool setInstall() const
00091       {
00092         if ( cand )
00093           {
00094               if ( inst ) {
00095                   inst.status().setTransact( false, ResStatus::USER );
00096                   inst.status().setLock    ( false, ResStatus::USER );
00097                   if ( ! cand->installOnly() )
00098                   {
00099                     // This is what the solver most probabely will do.
00100                     // If we are wrong the solver will correct it. But
00101                     // this way we will get a better disk usage result,
00102                     // even if no autosolving is on.
00103                     inst.status().setTransact( true,  ResStatus::SOLVER );
00104                   }
00105               }
00106               unlockCandidates();
00107               return cand.status().setTransact( true, ResStatus::USER );
00108           }
00109         return false;
00110       }
00111 
00112       bool setDelete() const
00113       {
00114         if ( inst )
00115           {
00116             resetTransactingCandidates();
00117             inst.status().setLock( false, ResStatus::USER );
00118             return inst.status().setTransact( true, ResStatus::USER );
00119           }
00120         return false;
00121       }
00122 
00123       bool unset() const
00124       {
00125           if ( inst ) {
00126               inst.status().setTransact( false, ResStatus::USER );
00127               inst.status().setLock( false, ResStatus::USER );
00128           }
00129           unlockCandidates();
00130           return true;
00131       }
00132 
00133       bool setProtected() const
00134       {
00135           if ( inst ) {
00136               resetTransactingCandidates();
00137               inst.status().setTransact( false, ResStatus::USER );
00138               return inst.status().setLock( true, ResStatus::USER );
00139           } else
00140               return false;
00141       }
00142 
00143       bool setTaboo() const
00144       {
00145           if ( cand ) {
00146               lockCandidates();
00147               return true;
00148           } else
00149               return false;
00150       }
00151 
00152 
00153     public:
00154       const Selectable::Impl & _impl;
00155       PoolItem inst;
00156       PoolItem cand;
00157     };
00159 
00161     //
00162     //  CLASS NAME : Selectable::Impl
00163     //
00165 
00166     Status Selectable::Impl::status() const
00167     {
00168       PoolItem cand( candidateObj() );
00169       if ( cand && cand.status().transacts() )
00170         {
00171           if ( cand.status().isByUser() )
00172             return( installedObj() ? S_Update : S_Install );
00173           else
00174             return( installedObj() ? S_AutoUpdate : S_AutoInstall );
00175         }
00176 
00177       if ( installedObj() && installedObj().status().transacts() )
00178         {
00179           return( installedObj().status().isByUser() ? S_Del : S_AutoDel );
00180         }
00181 
00182       if ( installedObj() && installedObj().status().isLocked() )
00183           return S_Protected;
00184 
00185       if ( !installedObj() && allCandidatesLocked() )
00186           return S_Taboo;
00187 
00188       return( installedObj() ? S_KeepInstalled : S_NoInst );
00189     }
00190 
00191     bool Selectable::Impl::set_status( const Status state_r )
00192     {
00193       StatusHelper self( *this );
00194 
00195       switch ( state_r )
00196         {
00197         case S_Protected:
00198             return self.setProtected();
00199         case S_Taboo:
00200             return self.setTaboo();
00201         case S_AutoDel:
00202         case S_AutoInstall:
00203         case S_AutoUpdate:
00204           // Auto level is SOLVER level. UI may query, but not
00205           // set at this level.
00206           break;
00207 
00208         case S_Del:
00209           return self.setDelete();
00210           break;
00211 
00212         case S_Install:
00213           return self.hasCandidateOnly() && self.setInstall();
00214           break;
00215 
00216         case S_Update:
00217           return self.hasBoth() && self.setInstall();
00218           break;
00219 
00220         case S_KeepInstalled:
00221           return self.hasInstalled() && self.unset();
00222           break;
00223 
00224         case S_NoInst:
00225           return !self.hasInstalled() && self.unset();
00226           break;
00227         }
00228 
00229       return false;
00230     }
00231 
00232     PoolItem Selectable::Impl::setCandidate( ResObject::constPtr byUser_r )
00233     {
00234       _candidate = PoolItem();
00235 
00236       if ( byUser_r ) // must be in available list
00237         {
00238           for ( availableItem_const_iterator it = availableBegin();
00239                 it != availableEnd(); ++it )
00240             {
00241               if ( it->resolvable() == byUser_r )
00242                 {
00243                   _candidate = *it;
00244                   break;
00245                 }
00246             }
00247         }
00248 
00249       if ( _candidate )
00250         {
00251           PoolItem trans( transactingCandidate() );
00252           if ( trans && trans != _candidate )
00253             {
00254               // adjust transact to the new cancidate
00255               trans.status().setTransact( false, ResStatus::USER );
00256               _candidate.status().setTransact( true, ResStatus::USER );
00257             }
00258         }
00259 
00260       return _candidate;
00261     }
00262 
00263     ResStatus::TransactByValue Selectable::Impl::modifiedBy() const
00264     {
00265       PoolItem cand( candidateObj() );
00266       if ( cand && cand.status().transacts() )
00267         return cand.status().getTransactByValue();
00268 
00269       if ( installedObj() && installedObj().status().transacts() )
00270         return installedObj().status().getTransactByValue();
00271 
00272       if ( cand )
00273         return cand.status().getTransactByValue();
00274 
00275       if ( installedObj() )
00276         return installedObj().status().getTransactByValue();
00277 
00278       return ResStatus::SOLVER;
00279     }
00280 
00282   } // namespace ui
00285 } // namespace zypp

Generated on Tue Sep 25 19:23:11 2007 for libzypp by  doxygen 1.5.3