Improve PickList status handling.
authorMichael Andres <ma@suse.de>
Fri, 4 Dec 2009 16:22:21 +0000 (17:22 +0100)
committerMichael Andres <ma@suse.de>
Fri, 4 Dec 2009 16:43:19 +0000 (17:43 +0100)
zypp/ui/Selectable.cc
zypp/ui/Selectable.h
zypp/ui/SelectableImpl.cc
zypp/ui/SelectableImpl.h

index bcb86a9..8473b94 100644 (file)
@@ -154,12 +154,18 @@ namespace zypp
     bool Selectable::multiversionInstall() const
     { return _pimpl->multiversionInstall(); }
 
-    bool Selectable::setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r )
-    { return _pimpl->setPickStatus( pi_r, state_r, causer_r ); }
+    bool Selectable::pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r )
+    { return _pimpl->pickInstall( pi_r, causer_r, yesno_r ); }
+
+    bool Selectable::pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r )
+    { return _pimpl->pickDelete( pi_r, causer_r, yesno_r ); }
 
     Status Selectable::pickStatus( const PoolItem & pi_r ) const
     { return _pimpl->pickStatus( pi_r ); }
 
+    bool Selectable::setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r )
+    { return _pimpl->setPickStatus( pi_r, state_r, causer_r ); }
+
     ////////////////////////////////////////////////////////////////////////
 
     bool Selectable::isUndetermined() const
index b439780..a15b14a 100644 (file)
@@ -308,8 +308,23 @@ namespace zypp
        */
       bool multiversionInstall() const;
 
-      /** */
-      bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
+      /** Select a specific available item for installation.
+       */
+      bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
+
+      /** Deselect a specific available item from installation.
+      */
+      bool pickNoInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
+      { return pickInstall( pi_r, causer_r, false ); }
+
+      /** Select a specific installed item for deletion.
+       */
+      bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
+
+      /** Deselect a specific installed item from deletion.
+       */
+      bool pickNoDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
+      { return pickDelete( pi_r, causer_r, false ); }
 
       /** Compute the \ref ui::Status for an individual PoolItem.
        * This just takes into account the item and any identical
@@ -335,6 +350,9 @@ namespace zypp
        * \see \ref sat::Solvable::identical
        */
       Status pickStatus( const PoolItem & pi_r ) const;
+
+      /** Assign a new status to a specific item. */
+      bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
       //@}
 
       /** \name Classification of available patches (pseudo installed items).
index 29c129b..b6a2016 100644 (file)
@@ -123,7 +123,7 @@ namespace zypp
     //
     // CLASS NAME : StatusHelper
     //
-    /**
+    /** \todo Unify status and pickStatus.
     */
     struct StatusHelper
     {
@@ -161,16 +161,19 @@ namespace zypp
         if ( cand )
         {
           if ( inst ) {
-            ResStatus & inststatus( backup( inst.status() ) );
-            if ( ! inststatus.setTransact( false, causer ) ) return restore();
-            if ( ! inststatus.setLock    ( false, causer ) ) return restore();
-            if ( ! cand->multiversionInstall() )
+            for_( it, _impl.installedBegin(), _impl.installedEnd() )
             {
+              ResStatus & inststatus( backup( it->status() ) );
+              if ( ! inststatus.setTransact( false, causer ) ) return restore();
+              if ( ! inststatus.setLock    ( false, causer ) ) return restore();
+              if ( ! cand->multiversionInstall() )
+              {
               // This is what the solver most probabely will do.
               // If we are wrong the solver will correct it. But
               // this way we will get a better disk usage result,
               // even if no autosolving is on.
-              inststatus.setTransact( true, ResStatus::SOLVER );
+                inststatus.setTransact( true, ResStatus::SOLVER );
+              }
             }
           }
           if ( ! unlockCandidates() ) return restore();
@@ -186,9 +189,12 @@ namespace zypp
         if ( inst )
         {
           if ( ! resetTransactingCandidates() ) return restore();
-          ResStatus & inststatus( backup( inst.status() ) );
-          if ( ! inststatus.setLock( false, causer ) ) return restore();
-          if ( ! inststatus.setTransact( true, causer ) ) return restore();
+          for_( it, _impl.installedBegin(), _impl.installedEnd() )
+          {
+            ResStatus & inststatus( backup( it->status() ) );
+            if ( ! inststatus.setLock( false, causer ) ) return restore();
+            if ( ! inststatus.setTransact( true, causer ) ) return restore();
+          }
           return true;
         }
         return false;
@@ -198,9 +204,12 @@ namespace zypp
       {
         if ( inst )
         {
-          ResStatus & inststatus( backup( inst.status() ) );
-          if ( ! inststatus.setTransact( false, causer ) ) return restore();
-          if ( ! inststatus.setLock( false, causer ) ) return restore();
+          for_( it, _impl.installedBegin(), _impl.installedEnd() )
+          {
+            ResStatus & inststatus( backup( it->status() ) );
+            if ( ! inststatus.setTransact( false, causer ) ) return restore();
+            if ( ! inststatus.setLock( false, causer ) ) return restore();
+          }
         }
         if ( ! unlockCandidates() ) return restore();
         return true;
@@ -213,8 +222,12 @@ namespace zypp
 
         if ( inst ) {
           resetTransactingCandidates();
-          inst.status().setTransact( false, causer );
-          return inst.status().setLock( true, causer );
+          for_( it, _impl.installedBegin(), _impl.installedEnd() )
+          {
+            it->status().setTransact( false, causer );
+            it->status().setLock( true, causer );
+          }
+          return true;
         } else
           return false;
       }
@@ -399,9 +412,22 @@ namespace zypp
     }
 
     ///////////////////////////////////////////////////////////////////
+
+    bool Selectable::Impl::pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r )
+    {
+      if ( identicalInstalled( pi_r ) )
+        return setPickStatus( pi_r, ( yesno_r ? S_Update : S_KeepInstalled ), causer_r );
+      return setPickStatus( pi_r, ( yesno_r ? S_Install : S_NoInst ), causer_r );
+    }
+
+    bool Selectable::Impl::pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r )
+    {
+      return setPickStatus( pi_r, ( yesno_r ? S_Del : S_KeepInstalled ), causer_r );
+    }
+
     bool Selectable::Impl::setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r )
     {
-      if ( pi_r.satSolvable().ident() == ident() )
+      if ( pi_r.satSolvable().ident() != ident() )
         return false;  // not my PoolItem
 
       if ( ! multiversionInstall() )
@@ -419,7 +445,7 @@ namespace zypp
           i.push_back( *it );
       for_( it, availableBegin(), availableEnd() )
         if ( identical( *it, pi_r ) )
-          i.push_back( *it );
+          a.push_back( *it );
 
       switch ( state_r )
       {
@@ -472,7 +498,10 @@ namespace zypp
           {
             if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
             if ( ! backup.forEach( i.begin(), i.end(), &StatusBackup::setTransactTrue, ResStatus::SOLVER ) ) return backup.restore();
-
+            // maybe unlock candidate only?
+            if ( ! backup.forEach( a.begin(), a.end(), &StatusBackup::unlock, causer_r ) ) return backup.restore();
+            const PoolItem & cand( pi_r.status().isInstalled() ? *a.begin() : pi_r ); // status already backed up above
+            if ( ! cand.status().setTransact( true, causer_r ) ) return backup.restore();
             return true;
           }
           break;
@@ -499,73 +528,69 @@ namespace zypp
 
     Status Selectable::Impl::pickStatus( const PoolItem & pi_r ) const
     {
-      if ( pi_r.satSolvable().ident() == ident() )
-      {
-        if ( pi_r.satSolvable().isSystem() )
-        {
-          // have installed!
-          if ( pi_r.status().isLocked() )
-            return S_Protected;
+      if ( pi_r.satSolvable().ident() != ident() )
+        return Status(-1); // not my PoolItem
 
-          // at least one identical available transacing?
-          for_( it, _availableItems.begin(), _availableItems.end() )
-          {
-            if ( identical( *it, pi_r ) )
-            {
-              if ( (*it).status().transacts() )
-                return( (*it).status().isByUser() ? S_Update : S_AutoUpdate );
-            }
-          }
+      std::vector<PoolItem> i;
+      std::vector<PoolItem> a;
+      PoolItem ti;
+      PoolItem ta;
 
-          // no update, so maybe delete?
-          if ( pi_r.status().transacts() )
-            return ( pi_r.status().isByUser() ? S_Del : S_AutoDel );
+      for_( it, installedBegin(), installedEnd() )
+        if ( identical( *it, pi_r ) )
+        {
+          i.push_back( *it );
+          if ( ! ti && it->status().transacts() )
+            ti = *it;
+        }
 
-          // keep
-          return S_KeepInstalled;
+      for_( it, availableBegin(), availableEnd() )
+        if ( identical( *it, pi_r ) )
+        {
+          a.push_back( *it );
+          if ( ! ta && it->status().transacts() )
+            ta = *it;
         }
+
+      if ( ta )
+      {
+        if ( ta.status().isByUser() )
+          return( i.empty() ? S_Install : S_Update );
         else
-        {
-          // have available!
-          if ( pi_r.status().isLocked() )
-            return S_Taboo;
+          return( i.empty() ? S_AutoInstall : S_AutoUpdate );
+      }
 
-          // have identical installed? (maybe transacting):
-          PoolItem inst;
-          for_( it, _installedItems.begin(), _installedItems.end() )
-          {
-            if ( identical( *it, pi_r ) )
-            {
-              if ( (*it).status().transacts() )
-              {
-                inst = *it;
-                break;
-              }
-              if ( !inst )
-                inst = *it;
-            }
-          }
+      if ( ti )
+      {
+        return( ti.status().isByUser() ? S_Del : S_AutoDel );
+      }
+
+      for_( it, i.begin(), i.end() )
+        if ( it->status().isLocked() )
+          return S_Protected;
 
-          // check for inst/update
-          if ( pi_r.status().transacts() )
+      if ( i.empty() )
+      {
+        bool allALocked = true;
+        for_( it, a.begin(), a.end() )
+          if ( ! it->status().isLocked() )
           {
-            if ( inst )
-              return( pi_r.status().isByUser() ? S_Update : S_AutoUpdate );
-            else
-              return( pi_r.status().isByUser() ? S_Install : S_AutoInstall );
+            allALocked = false;
+            break;
           }
+        if ( allALocked )
+          return S_Taboo;
+      }
 
-          // no inst/update, so maybe delete?
-          if ( ! inst )
-            return  S_NoInst;
-
-          if ( inst.status().transacts() )
-            return( inst.status().isByUser() ? S_Del : S_AutoDel );
+      // KEEP state:
+      if ( ! i.empty() )
+        return S_KeepInstalled;
+      // Report pseudo installed items as installed, if they are satisfied.
+      if ( traits::isPseudoInstalled( kind() )
+           && ( ta ? ta : *a.begin() ).status().isSatisfied() ) // no installed, so we must have candidate
+        return S_KeepInstalled;
 
-          return S_KeepInstalled;
-        }
-      }
-      return Status(-1); // not my PoolItem
+      return S_NoInst;
     }
 
     ///////////////////////////////////////////////////////////////////
index 9fc2e75..057299e 100644 (file)
@@ -285,10 +285,14 @@ namespace zypp
       bool multiversionInstall() const
       { return theObj().satSolvable().multiversionInstall(); }
 
-      bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r );
+      bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
+
+      bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
 
       Status pickStatus( const PoolItem & pi_r ) const;
 
+      bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r );
+
       ////////////////////////////////////////////////////////////////////////
 
       bool isUndetermined() const