support for automatic changes dialog
authorStefan Hundhammer <sh@suse.de>
Fri, 31 Mar 2006 15:53:27 +0000 (15:53 +0000)
committerStefan Hundhammer <sh@suse.de>
Fri, 31 Mar 2006 15:53:27 +0000 (15:53 +0000)
zypp/ui/Makefile.am
zypp/ui/UserWantedPackages.cc [new file with mode: 0644]
zypp/ui/UserWantedPackages.h [new file with mode: 0644]

index f8675c9..44ab0b9 100644 (file)
@@ -14,6 +14,7 @@ uiinclude_HEADERS =           \
        Selectable.h            \
        SelFilters.h            \
        SelectableTraits.h      \
+       UserWantedPackages.h    \
                                \
        PatchContentsImpl.h     \
        SelectableImpl.h
@@ -26,6 +27,7 @@ lib@PACKAGE@_ui_la_SOURCES =  \
        PatchContents.cc        \
        Status.cc               \
        Selectable.cc           \
+       UserWantedPackages.cc   \
                                \
        PatchContentsImpl.cc    \
        SelectableImpl.cc
diff --git a/zypp/ui/UserWantedPackages.cc b/zypp/ui/UserWantedPackages.cc
new file mode 100644 (file)
index 0000000..793efd3
--- /dev/null
@@ -0,0 +1,221 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/**
+ * \file       zypp/ui/UserWantedPackages.cc
+ *
+ *  \author    Stefan Hundhammer <sh@suse.de>
+ *
+ */
+
+#include "zypp/ui/UserWantedPackages.h"
+
+#include "zypp/ui/Status.h"
+#include "zypp/ui/Selectable.h"
+#include "zypp/ResObject.h"
+#include "zypp/Package.h"
+#include "zypp/Selection.h"
+#include "zypp/Pattern.h"
+#include "zypp/Language.h"
+#include "zypp/Patch.h"
+#include "zypp/ZYppFactory.h"
+#include "zypp/ResPoolProxy.h"
+
+
+using std::string;
+using std::set;
+using std::endl;
+
+
+namespace zypp
+{
+    namespace ui
+    {
+       typedef ResPoolProxy::const_iterator    PoolProxyIterator;
+
+        static inline ResPoolProxy             poolProxy()     { return getZYpp()->poolProxy();        }
+
+       template<class T> PoolProxyIterator poolProxyBegin()    { return poolProxy().byKindBegin<T>();  }
+       template<class T> PoolProxyIterator poolProxyEnd()      { return poolProxy().byKindEnd<T>();    }
+
+       static inline PoolProxyIterator pkgBegin()              { return poolProxyBegin<Package>();     }
+       static inline PoolProxyIterator pkgEnd()                { return poolProxyEnd<Package>();       }
+
+       static inline PoolProxyIterator langBegin()             { return poolProxyBegin<Language>();    }
+       static inline PoolProxyIterator langEnd()               { return poolProxyEnd<Language>();      }
+
+       static inline PoolProxyIterator patchesBegin()          { return poolProxyBegin<Patch>();       }
+       static inline PoolProxyIterator patchesEnd()            { return poolProxyEnd<Patch>();         }
+
+       template<typename T> bool contains( const std::set<T> & container, T search )
+       {
+           return container.find( search ) != container.end();
+       }
+
+
+
+       static void addDirectlySelectedPackages ( set<string> & pkgNames );
+        template<class PkgSet_T, class PkgSetPtr_T> void addPkgSetPackages( set<string> & pkgNames );
+
+       static void addSelectionPackages        ( set<string> & pkgNames );
+       static void addPatternPackages          ( set<string> & pkgNames );
+       static void addLanguagePackages         ( set<string> & pkgNames );
+       static void addPatchPackages            ( set<string> & pkgNames );
+
+
+
+       set<string> userWantedPackageNames()
+       {
+           set<string> pkgNames;
+
+           DBG << "Collecting packages the user explicitly asked for" << endl;
+           
+           addDirectlySelectedPackages ( pkgNames );
+           addSelectionPackages        ( pkgNames );
+           addPatternPackages          ( pkgNames );
+           addLanguagePackages         ( pkgNames );
+           addPatchPackages            ( pkgNames );
+
+           return pkgNames;
+       }
+
+
+
+       static void addDirectlySelectedPackages( set<string> & pkgNames )
+       {
+           for ( PoolProxyIterator it = pkgBegin();
+                 it != pkgEnd();
+                 ++it )
+           {
+               // Add all packages the user wanted to transact directly,
+               // no matter what the transaction is (install, update, delete)
+
+               if ( (*it)->toModify() && (*it)->modifiedBy() == ResStatus::USER )
+               {
+                   DBG << "Explicit user transaction on pkg " << (*it)->theObj()->name() << endl;
+                   pkgNames.insert( (*it)->theObj()->name() );
+               }
+           }
+       }
+
+
+
+       static void addSelectionPackages        ( set<string> & pkgNames )
+       {
+           addPkgSetPackages<Selection, Selection::constPtr>( pkgNames );
+       }
+
+
+       static void addPatternPackages          ( set<string> & pkgNames )
+       {
+           addPkgSetPackages<Pattern, Pattern::constPtr>( pkgNames );
+       }
+
+
+       /**
+        * Template to handle Selections and Patterns
+        **/
+        template<class PkgSet_T, class PkgSetPtr_T> void addPkgSetPackages( set<string> & pkgNames )
+       {
+           for ( PoolProxyIterator pkgSet_it = poolProxyBegin<PkgSet_T>();
+                 pkgSet_it != poolProxyBegin<PkgSet_T>();
+                 ++pkgSet_it )
+           {
+               // Take all pkg sets (selections or patterns) into account that
+               // will be transacted, no matter if the user explicitly asked
+               // for that pkg set or if the selection is required by another
+               // pkg set of the same class
+
+               PkgSetPtr_T pkgSet = dynamic_pointer_cast<const PkgSet_T>( (*pkgSet_it)->theObj() );
+
+               if ( pkgSet && (*pkgSet_it)->toModify() )
+               {
+                   DBG << "Pattern / selection " << pkgSet->name() << " will be transacted" << endl;
+                   set<string> setPkgs = pkgSet->install_packages();
+                   pkgNames.insert( setPkgs.begin(), setPkgs.end() );
+               }
+               else
+               {
+                   DBG << "Pattern / selection " << (*pkgSet_it)->name() << " not modified" << endl;
+               }
+           }
+       }
+
+
+
+       static void addLanguagePackages( set<string> & pkgNames )
+       {
+           // Build a set of all languages that are to be transacted
+
+           set<string> wantedLanguages;
+
+           for ( PoolProxyIterator lang_it = langBegin();
+                 lang_it != langEnd();
+                 ++lang_it )
+           {
+               Language::constPtr lang = dynamic_pointer_cast<const Language>( *lang_it );
+
+               if ( lang && (*lang_it)->toModify() )
+               {
+                   DBG << "Language " << lang->name() << " will be transacted" << endl;
+                   wantedLanguages.insert( lang->name() );
+               }
+           }
+
+
+           // Check all packages if they support any of the wanted languages
+
+           for ( PoolProxyIterator pkg_it = pkgBegin();
+                 pkg_it != pkgEnd();
+                 ++pkg_it )
+           {
+               ResObject::constPtr obj = (*pkg_it)->theObj();
+
+               if ( obj )
+               {
+                   CapSet freshens = obj->dep( Dep::FRESHENS );
+
+                   for ( CapSet::const_iterator cap_it = freshens.begin();
+                         cap_it != freshens.end();
+                         ++cap_it )
+                   {
+                       if ( contains( wantedLanguages, (*cap_it).index() ) )
+                           pkgNames.insert( obj->name() );
+                   }
+               }
+           }
+       }
+
+
+
+       static void addPatchPackages( set<string> & pkgNames )
+       {
+           for ( PoolProxyIterator patch_it = patchesBegin();
+                 patch_it != patchesEnd();
+                 ++patch_it )
+           {
+               Patch::constPtr patch = dynamic_pointer_cast<const Patch>( *patch_it );
+
+               if ( patch && (*patch_it)->toModify() )
+               {
+                   DBG << "Patch " << patch->name() << "(" << patch->summary() << ") will be transacted" << endl;
+
+                   Patch::AtomList atomList = patch->atoms();
+
+                   for ( Patch::AtomList::iterator atom_it = atomList.begin();
+                         atom_it != atomList.end();
+                         ++atom_it )
+                   {
+                       pkgNames.insert( (*atom_it)->name() );
+                   }
+               }
+           }
+       }
+
+    }
+}
diff --git a/zypp/ui/UserWantedPackages.h b/zypp/ui/UserWantedPackages.h
new file mode 100644 (file)
index 0000000..0ce6c3f
--- /dev/null
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/**
+ * \file       zypp/ui/UserWantedPackages.h
+ *
+ *  \author    Stefan Hundhammer <sh@suse.de>
+ *
+ */
+#ifndef USER_WANTED_PACKAGES_H
+#define USER_WANTED_PACKAGES_H
+
+#include <set>
+#include <string>
+
+namespace zypp
+{
+    namespace ui
+    {
+       /**
+        * This returns a set of package names the user explicitly wanted to
+        * transact ( to install, to update, or to delete) for any of the
+        * following reasons:
+        *
+        * - The user wanted to transact the pkg directly
+        *
+        * - Pkg is part of a selection the user wanted to transact
+        * - Pkg is part of a pattern   the user wanted to transact
+        * - Pkg is part of a language  the user wanted to transact
+        * - Pkg is part of a patch     the user wanted to transact
+        *
+        * - Pkg is part of a selection that is required by a selection the
+        *   user wanted to transact
+        *
+        * - Pkg is part of a pattern that is required by a pattern the
+        *   user wanted to transact
+        **/
+       std::set<std::string> userWantedPackageNames();
+
+    } // namespace ui
+} // namespace zypp
+
+#endif // USER_WANTED_PACKAGES_H