Imported Upstream version 14.48.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        * The \ref locked status indicates that \b all installed and/or \b all available
420        * items are locked. So you can't remove and/or can't install any item. This
421        * is the common case.
422        * \see \ref hasLocks
423        */
424       bool locked() const
425       { Status st( status() ); return( st == S_Protected || st == S_Taboo ); }
426
427       /** True if it includes locked items (don't mix this with the \ref locked status).
428        * This is also \c true for partially locked items, where only specific versions
429        * are locked.
430        * \see \ref locked
431        */
432       bool hasLocks() const;
433
434       /** True if either to delete or to install */
435       bool toModify() const
436       { return fate() != UNMODIFIED; }
437
438       /** True if to delete */
439       bool toDelete() const
440       { return fate() == TO_DELETE; }
441
442       /** True if to install */
443       bool toInstall() const
444       { return fate() == TO_INSTALL; }
445
446       /** True if would be on system after commit. */
447       bool onSystem() const
448       { return( ( hasInstalledObj() && !toDelete() )
449               ||( hasCandidateObj() && toInstall() ) ); }
450
451       /** True if would be off system after commit. */
452       bool offSystem() const
453       { return ! onSystem(); }
454
455       /** */
456       bool setFate( Fate fate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
457
458       /** Set the item to be installed (new- or re-install). */
459       bool setToInstall( ResStatus::TransactByValue causer_r = ResStatus::USER )
460       { return setFate( TO_INSTALL, causer_r ); }
461
462       /** Take care the item gets installed if it is not. */
463       bool setInstalled( ResStatus::TransactByValue causer_r = ResStatus::USER );
464
465       /** Take care the item gets installed if it is not, or is older. */
466       bool setUpToDate( ResStatus::TransactByValue causer_r = ResStatus::USER );
467
468       /** Set the item to be deleted (must be installed). */
469       bool setToDelete( ResStatus::TransactByValue causer_r = ResStatus::USER )
470       { return setFate( TO_DELETE, causer_r ); }
471
472       /** Take care the item gets deleted if it is installed. */
473       bool setDeleted( ResStatus::TransactByValue causer_r = ResStatus::USER );
474
475       /** Set the item to stay unmodified. */
476       bool unset( ResStatus::TransactByValue causer_r = ResStatus::USER )
477       { return setFate( UNMODIFIED, causer_r ); }
478       //@}
479
480     public:
481       /**
482        * \name Special inteface for Y2UI.
483        * \note This interface acts on \ref ResStatus::USER level.
484        * The \ref Status enum, and allowed state transitions are
485        * tightly related to the Y2UI.
486       */
487       //@{
488       /** Return the current Status */
489       Status status() const;
490
491       /**
492        * Try to set a new Status.
493        * Returns \c false if the transitions is not allowed.
494        */
495       bool setStatus( Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
496
497       /** Return who caused the modification. */
498       ResStatus::TransactByValue modifiedBy() const;
499
500       /** Return value of LicenceConfirmed bit. */
501       bool hasLicenceConfirmed() const;
502
503       /** Set LicenceConfirmed bit. */
504       void setLicenceConfirmed( bool val_r = true );
505       //@}
506
507     public:
508       /** Implementation  */
509       class Impl;
510       typedef shared_ptr<Impl> Impl_Ptr;
511       /** Default ctor */
512       Selectable( Impl_Ptr pimpl_r );
513     private:
514       /** Dtor */
515       ~Selectable();
516     private:
517       /** Pointer to implementation */
518       RW_pointer<Impl> _pimpl;
519     };
520     ///////////////////////////////////////////////////////////////////
521
522     /** \relates Selectable Stream output */
523     std::ostream & operator<<( std::ostream & str, const Selectable & obj );
524
525     /** \relates Selectable More verbose stream output */
526     std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
527
528     /** Solvable to Selectable transform functor.
529      * \relates Selectable
530      * \relates sat::SolvIterMixin
531      */
532     struct asSelectable
533     {
534       typedef Selectable_Ptr result_type;
535
536       Selectable_Ptr operator()( const sat::Solvable & solv_r ) const;
537
538       Selectable_Ptr operator()( const PoolItem & pi_r ) const
539       { return operator()( pi_r.satSolvable() ); }
540     };
541
542     /////////////////////////////////////////////////////////////////
543   } // namespace ui
544   ///////////////////////////////////////////////////////////////////
545   /////////////////////////////////////////////////////////////////
546 } // namespace zypp
547 ///////////////////////////////////////////////////////////////////
548 #endif // ZYPP_UI_SELECTABLE_H