Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / ui / Selectable.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ui/Selectable.h
10  *
11 */
12 #ifndef ZYPP_UI_SELECTABLE_H
13 #define ZYPP_UI_SELECTABLE_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/ReferenceCounted.h"
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Iterator.h"
21
22 #include "zypp/ui/SelectableTraits.h"
23 #include "zypp/ui/Status.h"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29   ///////////////////////////////////////////////////////////////////
30   namespace ui
31   { /////////////////////////////////////////////////////////////////
32
33     DEFINE_PTR_TYPE(Selectable);
34
35     ///////////////////////////////////////////////////////////////////
36     //
37     //  CLASS NAME : Selectable
38     //
39     /** Collects PoolItems of same kind and name.
40      *
41      * Selectable is a status wrapper. The ui::Status is calculated
42      * from (and transated to) \ref PoolItems individual \ref ResStatus
43      * values.
44      *
45      * Available objects are sorted according the solver policies, 'best'
46      * packages first (e.g. by repository priority, then Arch, then Edition).
47      *
48      * Installed objects are sorted according the installation date, newer install
49      * time first.
50     */
51     class Selectable : public base::ReferenceCounted, private base::NonCopyable
52     {
53       friend std::ostream & operator<<( std::ostream & str, const Selectable & obj );
54       friend std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
55
56     public:
57       typedef intrusive_ptr<Selectable>        Ptr;
58       typedef intrusive_ptr<const Selectable>  constPtr;
59
60       /** Iterates over ResObject::constPtr */
61       typedef SelectableTraits::available_iterator      available_iterator;
62       typedef SelectableTraits::available_size_type     available_size_type;
63
64       typedef SelectableTraits::installed_iterator      installed_iterator;
65       typedef SelectableTraits::installed_size_type     installed_size_type;
66
67       typedef SelectableTraits::picklist_iterator       picklist_iterator;
68       typedef SelectableTraits::picklist_size_type      picklist_size_type;
69
70     public:
71       /** \name Static ctor substitues picking the item from the pool.
72        * \code
73        * Selectable::Ptr item;
74        * item = Selectable::get( "amarok );                  // package amamrok
75        * item = Selectable::get( ResKind::patch, "amarok );  // patch amamrok
76        * item = Selectable::get( IdString( "patch:amarok" ); // patch amamrok
77        * \endcode
78       */
79       //@{
80       /** Get the \ref Selctable */
81       static Ptr get( const pool::ByIdent & ident_r );
82
83       /** Get the \ref Selctable by it's \c sat-identifyer. */
84       static Ptr get( IdString ident_r )
85       { return get( pool::ByIdent( ident_r ) ); }
86
87       /** Get the \ref Selctable by \c kind and \c name. */
88       static Ptr get( ResKind kind_r, const std::string & name_r )
89       { return get( pool::ByIdent( kind_r, name_r ) ); }
90
91       /** Get the \c Package \ref Selctable by \c name. */
92       static Ptr get( const std::string & name_r )
93       { return get( pool::ByIdent( ResKind::package, name_r ) ); }
94
95       /** Get the \ref Selctable containing a specific \ref sat::Solvable. */
96       static Ptr get( const sat::Solvable & solv_r )
97       { return get( pool::ByIdent( solv_r ) ); }
98
99       /** Get the \ref Selctable containing a specific \ref ResObject. */
100       static Ptr get( const ResObject::constPtr & resolvable_r )
101       { return resolvable_r ? get( resolvable_r->satSolvable() ) : Ptr(); }
102
103       /** Get the \ref Selctable containing a specific \ref PoolItem. */
104       static Ptr get( const PoolItem & pi_r )
105       { return get( pi_r.satSolvable() ); }
106       //@}
107
108     public:
109       /** The identifier.
110        * This is the solvables \ref name, \b except for packages and
111        * source packes, prefixed by it's \ref kind.
112        * \see \ref sat::Solvable.
113        */
114       IdString ident() const;
115
116       /** The ResObjects kind. */
117       ResObject::Kind kind() const;
118
119       /** The ResObjects name.  */
120       const std::string & name() const;
121
122       /** The last Installed object. */
123       PoolItem installedObj() const;
124
125       /** The 'best' or 'most interesting' among all available objects.
126        * One that is, or is likely to be, chosen for installation, unless
127        * it violated any solver policy (see \ref updateCandidateObj).
128        */
129       PoolItem candidateObj() const;
130
131       /** The best candidate provided by a specific \ref Repository, if there is one.
132        * In contrary to \ref candidateObj, this may return no item even if
133        * there are available objects. This simply means the \ref Repository
134        * does not provide this object.
135        */
136       PoolItem candidateObjFrom( Repository repo_r ) const;
137
138       /** The best candidate for update, if there is one.
139        * In contrary to \ref candidateObj, this may return no item even if
140        * there are available objects. This simply means the best object is
141        * already installed, and all available objects violate at least one
142        * update policy.
143        */
144       PoolItem updateCandidateObj() const;
145
146       /** Simply the highest available version, ignoring priorities and policies.
147        * It's doubtful whether solely looking at the version makes a good
148        * candidate, but apps ask for it. Beware that different vendors may
149        * use different (uncomparable) version schemata.
150        */
151       PoolItem highestAvailableVersionObj() const;
152
153      /** \c True if \a rhs is installed and one with the same content is available.
154        * Basically the same name, edition, arch, vendor and buildtime.
155        * \see \ref sat::Solvable::identical
156        */
157       bool identicalAvailable( const PoolItem & rhs ) const;
158
159      /** \c True if \a rhs has the same content as an installed one.
160        * Basically the same name, edition, arch, vendor and buildtime.
161        * \see \ref sat::Solvable::identical
162        */
163       bool identicalInstalled( const PoolItem & rhs ) const;
164
165       /** \c True if the \ref candidateObj is installed (same content).
166        * \see \ref identicalInstalled.
167        */
168       bool identicalInstalledCandidate() const
169       { return identicalInstalled( candidateObj() ); }
170
171       /** \c True if the \ref updateCandidateObj is installed (same content).
172        * \see \ref identicalInstalled.
173        */
174       bool identicalInstalledUpdateCandidate() const
175       { return identicalInstalled( updateCandidateObj() ); }
176
177       /** Return an available Object with the same content as \c rhs.
178        * Basically the same name, edition, arch, vendor and buildtime.
179        * \see \ref sat::Solvable::identical
180        */
181       PoolItem identicalAvailableObj( const PoolItem & rhs ) const;
182
183      /** \Return an installed Object with the same content as \c rhs.
184        * Basically the same name, edition, arch, vendor and buildtime.
185        * \see \ref sat::Solvable::identical
186        */
187       PoolItem identicalInstalledObj( const PoolItem & rhs ) const;
188
189       /** Return the \ref installedObj resolvable casted to a specific kind.
190        * \code
191        *   Selectable mySelectable;
192        *   Package::constPtr p( mySelectable.installedAsKind<Package>() );
193        * \endcode
194       */
195       template<class _Res>
196       typename ResTraits<_Res>::constPtrType installedAsKind() const
197       { return asKind<_Res>( candidateObj() ); }
198
199       /** Return the \ref candidateObj resolvable casted to a specific kind.
200        * \code
201        *   Selectable mySelectable;
202        *   Package::constPtr p( mySelectable.candidateAsKind<Package>() );
203        * \endcode
204       */
205       template<class _Res>
206       typename ResTraits<_Res>::constPtrType candidateAsKind() const
207       { return asKind<_Res>( candidateObj() ); }
208
209       /** Set a candidate (out of available objects).
210        * \return The new candidate, or NULL if choice was invalid
211        * (NULL or not among availableObjs). An invalid choice
212        * selects the default candidate.
213        * In case the causer is not \c ResStatus::USER the operation
214        * may also fail if there are insufficient permissions to change
215        * a transacting candidate.
216        */
217       PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
218       /** \overload */
219       PoolItem setCandidate( ResObject::constPtr newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
220
221       /** Arrange the specified candidate (out of available objects) to be on system after commit.
222        * If the specified candidate is not already installed (\ref identicalInstalled),
223        * and the \a causer_r has sufficient permisssion, then \a newCandidate_r is set as the new
224        * candidate (\ref setCandidate) and selected for installation.
225        * \returns \c True if \a newCandidate_r is already installed or successfully selected for installation.
226        */
227       bool setOnSystem( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
228
229       /** An object you could use as pars pro toto.
230        *
231        * \return the \ref candidateObj, or ,if no available objects
232        * exist, the \ref installedObj.
233        */
234       PoolItem theObj() const;
235
236       ////////////////////////////////////////////////////////////////////////
237
238       /** \name Available objects iterators.
239        * Oredered according to solver policy. 'Best' first.
240       */
241       //@{
242       bool availableEmpty() const;
243       available_size_type availableSize() const;
244       available_iterator availableBegin() const;
245       available_iterator availableEnd() const;
246       //@}
247
248       ////////////////////////////////////////////////////////////////////////
249
250       /** \name Installed objects iterators.
251        * Ordered by install time. Latest first.
252       */
253       //@{
254       bool installedEmpty() const;
255       installed_size_type installedSize() const;
256       installed_iterator installedBegin() const;
257       installed_iterator installedEnd() const;
258       //}
259
260       ////////////////////////////////////////////////////////////////////////
261
262       /** \name picklist iterators.
263        * This is basically the available items list prepended by those
264        * installed items, that are nolonger \ref identicalAvailable.
265        */
266       //@{
267       bool picklistEmpty() const;
268       picklist_size_type picklistSize() const;
269       picklist_iterator picklistBegin() const;
270       picklist_iterator picklistEnd() const;
271       //}
272
273       ////////////////////////////////////////////////////////////////////////
274
275     public:
276       /** \name Query for objects within this Selectable.
277       */
278       //@{
279       /** True if either installed or candidate object is present */
280       bool hasObject() const
281       { return (! installedEmpty()) || candidateObj(); }
282
283       /** True if installed object is present. */
284       bool hasInstalledObj() const
285       { return ! installedEmpty(); }
286
287       /** True if candidate object is present. */
288       bool hasCandidateObj() const
289       { return bool(candidateObj()); }
290
291       /** True if installed and candidate object is present */
292       bool hasBothObjects() const
293       { return (! installedEmpty()) && candidateObj(); }
294
295       /** True if installed object is present but no candidate. */
296       bool hasInstalledObjOnly() const
297       { return (! installedEmpty()) && ! candidateObj(); }
298
299       /** True if candidate object is present but no installed. */
300       bool hasCandidateObjOnly() const
301       { return ( installedEmpty() ) && candidateObj(); }
302       //@}
303
304       /**
305        * True if this package has no replacement from
306        * the available repositories
307        */
308       bool isUnmaintained() const;
309
310       /** \name Multiversion install.
311        *
312        * Using \ref pickInstall or \ref pickDelete with non-multiversionInstall items
313        * is possible, but additional constraints will apply. E.g. selecting one item for
314        * install will deselect any other.
315        */
316       //@{
317       /** Whether different versions of this package can be installed at the same time.
318        * Per default \c false. \see also \ref ZConfig::multiversion.
319        */
320       bool multiversionInstall() const;
321
322       /** Select a specific available item for installation.
323        */
324       bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
325
326       /** Deselect a specific available item from installation.
327       */
328       bool pickNoInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
329       { return pickInstall( pi_r, causer_r, false ); }
330
331       /** Select a specific installed item for deletion.
332        */
333       bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
334
335       /** Deselect a specific installed item from deletion.
336        */
337       bool pickNoDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
338       { return pickDelete( pi_r, causer_r, false ); }
339
340       /** Compute the \ref ui::Status for an individual PoolItem.
341        * This just takes into account the item and any identical
342        * installed (or available) one.
343        * \code
344        *   Assume there are 3 identical 'foo-1.1 (vendor A)' items,
345        *   one 'foo-2.1 (vendor A)' and one ''foo-1.1 (vendor B)':
346        *
347        *   installed: . foo-1.1 (vendor A)          -> S_KeepInstalled
348        *   available:   foo-2.1 (vendor A) (repo 1) -> S_NoInst
349        *              . foo-1.1 (vendor A) (repo 1) -> S_KeepInstalled
350        *              . foo-1.1 (vendor A) (repo 2) -> S_KeepInstalled
351        *                foo-1.1 (vendor B) (repo 3) -> S_NoInst
352        *
353        *   After 'foo-1.1 (vendor A) (repo 1)' was selected to be installed:
354        *
355        *   installed: . foo-1.1 (vendor A)          -> S_Update
356        *   available:   foo-2.1 (vendor A) (repo 1) -> S_NoInst
357        *              I foo-1.1 (vendor A) (repo 1) -> S_Update
358        *              . foo-1.1 (vendor A) (repo 2) -> S_KeepInstalled
359        *                foo-1.1 (vendor B) (repo 3) -> S_NoInst
360        * \endcode
361        * \see \ref sat::Solvable::identical
362        */
363       Status pickStatus( const PoolItem & pi_r ) const;
364
365       /** Assign a new status to a specific item. */
366       bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
367       //@}
368
369       /** \name Classification of available patches (pseudo installed items).
370        * A patch is either \c not \c relevant, \c satisfied or \c broken.
371        * The same applies to other pseudo installed kinds.
372        * \see \ref traits::isPseudoInstalled
373        */
374       //@{
375       /** Returns true for packages, because packages are not
376        * classified by the solver.
377        */
378       bool isUndetermined() const;
379
380       /** Returns true if the patch is relevant which means that at least
381        *  one package of the patch is installed.
382        */
383       bool isRelevant() const;
384
385       /** Whether a relevant patchs requirements are met. */
386       bool isSatisfied() const;
387
388       /** Whether a relevant patchs requirements are broken. */
389       bool isBroken() const;
390
391       /** This includes \c unlocked broken patches, as well as those already
392        * selected to be installed. This is because already selected
393        * patches will be classified as \c satisfied. \c Locked but broken
394        * patches will be classified as \ref isUnwanted.
395        */
396       bool isNeeded() const;
397
398       /** Broken (needed) but locked patches. */
399        bool isUnwanted() const;
400       //@}
401
402      public:
403       /** \name Query and maip objects fate in case of commit.
404        */
405       //@{
406       enum Fate {
407         TO_DELETE  = -1,
408         UNMODIFIED = 0,
409         TO_INSTALL = 1
410       };
411       /**  */
412       Fate fate() const;
413
414       /** True if neither to delete or to install */
415       bool unmodified() const
416       { return fate() == UNMODIFIED; }
417
418       /** True if locked (subclass of unmodified). */
419       bool locked() const
420       { Status st( status() ); return( st == S_Protected || st == S_Taboo ); }
421
422       /** True if either to delete or to install */
423       bool toModify() const
424       { return fate() != UNMODIFIED; }
425
426       /** True if to delete */
427       bool toDelete() const
428       { return fate() == TO_DELETE; }
429
430       /** True if to install */
431       bool toInstall() const
432       { return fate() == TO_INSTALL; }
433
434       /** True if would be on system after commit. */
435       bool onSystem() const
436       { return( ( hasInstalledObj() && !toDelete() )
437               ||( hasCandidateObj() && toInstall() ) ); }
438
439       /** True if would be off system after commit. */
440       bool offSystem() const
441       { return ! onSystem(); }
442
443       /** */
444       bool setFate( Fate fate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
445
446       /** Set the item to be installed (new- or re-install). */
447       bool setToInstall( ResStatus::TransactByValue causer_r = ResStatus::USER )
448       { return setFate( TO_INSTALL, causer_r ); }
449
450       /** Take care the item gets installed if it is not. */
451       bool setInstalled( ResStatus::TransactByValue causer_r = ResStatus::USER );
452
453       /** Take care the item gets installed if it is not, or is older. */
454       bool setUpToDate( ResStatus::TransactByValue causer_r = ResStatus::USER );
455
456       /** Set the item to be deleted (must be installed). */
457       bool setToDelete( ResStatus::TransactByValue causer_r = ResStatus::USER )
458       { return setFate( TO_DELETE, causer_r ); }
459
460       /** Take care the item gets deleted if it is installed. */
461       bool setDeleted( ResStatus::TransactByValue causer_r = ResStatus::USER );
462
463       /** Set the item to stay unmodified. */
464       bool unset( ResStatus::TransactByValue causer_r = ResStatus::USER )
465       { return setFate( UNMODIFIED, causer_r ); }
466       //@}
467
468     public:
469       /**
470        * \name Special inteface for Y2UI.
471        * \note This interface acts on \ref ResStatus::USER level.
472        * The \ref Status enum, and allowed state transitions are
473        * tightly related to the Y2UI.
474       */
475       //@{
476       /** Return the current Status */
477       Status status() const;
478
479       /**
480        * Try to set a new Status.
481        * Returns \c false if the transitions is not allowed.
482        */
483       bool setStatus( Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
484
485       /** Return who caused the modification. */
486       ResStatus::TransactByValue modifiedBy() const;
487
488       /** Return value of LicenceConfirmed bit. */
489       bool hasLicenceConfirmed() const;
490
491       /** Set LicenceConfirmed bit. */
492       void setLicenceConfirmed( bool val_r = true );
493       //@}
494
495     public:
496       /** Implementation  */
497       class Impl;
498       typedef shared_ptr<Impl> Impl_Ptr;
499       /** Default ctor */
500       Selectable( Impl_Ptr pimpl_r );
501     private:
502       /** Dtor */
503       ~Selectable();
504     private:
505       /** Pointer to implementation */
506       RW_pointer<Impl> _pimpl;
507     };
508     ///////////////////////////////////////////////////////////////////
509
510     /** \relates Selectable Stream output */
511     std::ostream & operator<<( std::ostream & str, const Selectable & obj );
512
513     /** \relates Selectable More verbose stream output */
514     std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
515
516     /** Solvable to Selectable transform functor.
517      * \relates Selectable
518      * \relates sat::SolvIterMixin
519      */
520     struct asSelectable
521     {
522       typedef Selectable_Ptr result_type;
523
524       Selectable_Ptr operator()( const sat::Solvable & solv_r ) const;
525
526       Selectable_Ptr operator()( const PoolItem & pi_r ) const
527       { return operator()( pi_r.satSolvable() ); }
528     };
529
530     /////////////////////////////////////////////////////////////////
531   } // namespace ui
532   ///////////////////////////////////////////////////////////////////
533   /////////////////////////////////////////////////////////////////
534 } // namespace zypp
535 ///////////////////////////////////////////////////////////////////
536 #endif // ZYPP_UI_SELECTABLE_H