41193267e294eace988a6cbcb33e23676f50237a
[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       ResKind 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       inline Iterable<available_iterator>  available() const
247       { return makeIterable( availableBegin(), availableEnd() ); }
248       //@}
249
250       ////////////////////////////////////////////////////////////////////////
251
252       /** \name Installed objects iterators.
253        * Ordered by install time. Latest first.
254       */
255       //@{
256       bool installedEmpty() const;
257       installed_size_type installedSize() const;
258       installed_iterator installedBegin() const;
259       installed_iterator installedEnd() const;
260       inline Iterable<installed_iterator> installed() const
261       { return makeIterable( installedBegin(), installedEnd() ); }
262       //@}
263
264       ////////////////////////////////////////////////////////////////////////
265
266       /** \name picklist iterators.
267        * This is basically the available items list prepended by those
268        * installed items, that are nolonger \ref identicalAvailable.
269        */
270       //@{
271       bool picklistEmpty() const;
272       picklist_size_type picklistSize() const;
273       picklist_iterator picklistBegin() const;
274       picklist_iterator picklistEnd() const;
275       inline Iterable<picklist_iterator> picklist() const
276       { return makeIterable( picklistBegin(), picklistEnd() ); }
277       //@}
278
279       ////////////////////////////////////////////////////////////////////////
280
281     public:
282       /** \name Query for objects within this Selectable.
283       */
284       //@{
285       /** True if either installed or candidate object is present */
286       bool hasObject() const
287       { return (! installedEmpty()) || candidateObj(); }
288
289       /** True if installed object is present. */
290       bool hasInstalledObj() const
291       { return ! installedEmpty(); }
292
293       /** True if candidate object is present. */
294       bool hasCandidateObj() const
295       { return bool(candidateObj()); }
296
297       /** True if installed and candidate object is present */
298       bool hasBothObjects() const
299       { return (! installedEmpty()) && candidateObj(); }
300
301       /** True if installed object is present but no candidate. */
302       bool hasInstalledObjOnly() const
303       { return (! installedEmpty()) && ! candidateObj(); }
304
305       /** True if candidate object is present but no installed. */
306       bool hasCandidateObjOnly() const
307       { return ( installedEmpty() ) && candidateObj(); }
308       //@}
309
310       /**
311        * True if this package has no replacement from
312        * the available repositories
313        */
314       bool isUnmaintained() const;
315
316       /** \name Multiversion install.
317        *
318        * Using \ref pickInstall or \ref pickDelete with non-multiversionInstall items
319        * is possible, but additional constraints will apply. E.g. selecting one item for
320        * install will deselect any other.
321        */
322       //@{
323       /** Whether at least one of the available packages has multiversionInstall set.
324        * \see \ref Solvable::multiversionInstall
325        * \see also \ref ZConfig::multiversion.
326        */
327       bool multiversionInstall() const;
328
329       /** Select a specific available item for installation.
330        */
331       bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
332
333       /** Deselect a specific available item from installation.
334       */
335       bool pickNoInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
336       { return pickInstall( pi_r, causer_r, false ); }
337
338       /** Select a specific installed item for deletion.
339        */
340       bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
341
342       /** Deselect a specific installed item from deletion.
343        */
344       bool pickNoDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
345       { return pickDelete( pi_r, causer_r, false ); }
346
347       /** Compute the \ref ui::Status for an individual PoolItem.
348        * This just takes into account the item and any identical
349        * installed (or available) one.
350        * \code
351        *   Assume there are 3 identical 'foo-1.1 (vendor A)' items,
352        *   one 'foo-2.1 (vendor A)' and one ''foo-1.1 (vendor B)':
353        *
354        *   installed: . foo-1.1 (vendor A)          -> S_KeepInstalled
355        *   available:   foo-2.1 (vendor A) (repo 1) -> S_NoInst
356        *              . foo-1.1 (vendor A) (repo 1) -> S_KeepInstalled
357        *              . foo-1.1 (vendor A) (repo 2) -> S_KeepInstalled
358        *                foo-1.1 (vendor B) (repo 3) -> S_NoInst
359        *
360        *   After 'foo-1.1 (vendor A) (repo 1)' was selected to be installed:
361        *
362        *   installed: . foo-1.1 (vendor A)          -> S_Update
363        *   available:   foo-2.1 (vendor A) (repo 1) -> S_NoInst
364        *              I foo-1.1 (vendor A) (repo 1) -> S_Update
365        *              . foo-1.1 (vendor A) (repo 2) -> S_KeepInstalled
366        *                foo-1.1 (vendor B) (repo 3) -> S_NoInst
367        * \endcode
368        * \see \ref sat::Solvable::identical
369        */
370       Status pickStatus( const PoolItem & pi_r ) const;
371
372       /** Assign a new status to a specific item. */
373       bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
374       //@}
375
376       /** \name Classification of available patches (pseudo installed items).
377        * A patch is either \c not \c relevant, \c satisfied or \c broken.
378        * The same applies to other pseudo installed kinds.
379        * \see \ref traits::isPseudoInstalled
380        */
381       //@{
382       /** Returns true for packages, because packages are not
383        * classified by the solver.
384        */
385       bool isUndetermined() const;
386
387       /** Returns true if the patch is relevant which means that at least
388        *  one package of the patch is installed.
389        */
390       bool isRelevant() const;
391
392       /** Whether a relevant patchs requirements are met. */
393       bool isSatisfied() const;
394
395       /** Whether a relevant patchs requirements are broken. */
396       bool isBroken() const;
397
398       /** This includes \c unlocked broken patches, as well as those already
399        * selected to be installed. This is because already selected
400        * patches will be classified as \c satisfied. \c Locked but broken
401        * patches will be classified as \ref isUnwanted.
402        */
403       bool isNeeded() const;
404
405       /** Broken (needed) but locked patches. */
406        bool isUnwanted() const;
407       //@}
408
409      public:
410       /** \name Query and maip objects fate in case of commit.
411        */
412       //@{
413       enum Fate {
414         TO_DELETE  = -1,
415         UNMODIFIED = 0,
416         TO_INSTALL = 1
417       };
418       /**  */
419       Fate fate() const;
420
421       /** True if neither to delete or to install */
422       bool unmodified() const
423       { return fate() == UNMODIFIED; }
424
425       /** True if locked (subclass of unmodified). */
426       bool locked() const
427       { Status st( status() ); return( st == S_Protected || st == S_Taboo ); }
428
429       /** True if either to delete or to install */
430       bool toModify() const
431       { return fate() != UNMODIFIED; }
432
433       /** True if to delete */
434       bool toDelete() const
435       { return fate() == TO_DELETE; }
436
437       /** True if to install */
438       bool toInstall() const
439       { return fate() == TO_INSTALL; }
440
441       /** True if would be on system after commit. */
442       bool onSystem() const
443       { return( ( hasInstalledObj() && !toDelete() )
444               ||( hasCandidateObj() && toInstall() ) ); }
445
446       /** True if would be off system after commit. */
447       bool offSystem() const
448       { return ! onSystem(); }
449
450       /** */
451       bool setFate( Fate fate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
452
453       /** Set the item to be installed (new- or re-install). */
454       bool setToInstall( ResStatus::TransactByValue causer_r = ResStatus::USER )
455       { return setFate( TO_INSTALL, causer_r ); }
456
457       /** Take care the item gets installed if it is not. */
458       bool setInstalled( ResStatus::TransactByValue causer_r = ResStatus::USER );
459
460       /** Take care the item gets installed if it is not, or is older. */
461       bool setUpToDate( ResStatus::TransactByValue causer_r = ResStatus::USER );
462
463       /** Set the item to be deleted (must be installed). */
464       bool setToDelete( ResStatus::TransactByValue causer_r = ResStatus::USER )
465       { return setFate( TO_DELETE, causer_r ); }
466
467       /** Take care the item gets deleted if it is installed. */
468       bool setDeleted( ResStatus::TransactByValue causer_r = ResStatus::USER );
469
470       /** Set the item to stay unmodified. */
471       bool unset( ResStatus::TransactByValue causer_r = ResStatus::USER )
472       { return setFate( UNMODIFIED, causer_r ); }
473       //@}
474
475     public:
476       /**
477        * \name Special inteface for Y2UI.
478        * \note This interface acts on \ref ResStatus::USER level.
479        * The \ref Status enum, and allowed state transitions are
480        * tightly related to the Y2UI.
481       */
482       //@{
483       /** Return the current Status */
484       Status status() const;
485
486       /**
487        * Try to set a new Status.
488        * Returns \c false if the transitions is not allowed.
489        */
490       bool setStatus( Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
491
492       /** Return who caused the modification. */
493       ResStatus::TransactByValue modifiedBy() const;
494
495       /** Return value of LicenceConfirmed bit. */
496       bool hasLicenceConfirmed() const;
497
498       /** Set LicenceConfirmed bit. */
499       void setLicenceConfirmed( bool val_r = true );
500       //@}
501
502     public:
503       /** Implementation  */
504       class Impl;
505       typedef shared_ptr<Impl> Impl_Ptr;
506       /** Default ctor */
507       Selectable( Impl_Ptr pimpl_r );
508     private:
509       /** Dtor */
510       ~Selectable();
511     private:
512       /** Pointer to implementation */
513       RW_pointer<Impl> _pimpl;
514     };
515     ///////////////////////////////////////////////////////////////////
516
517     /** \relates Selectable Stream output */
518     std::ostream & operator<<( std::ostream & str, const Selectable & obj );
519
520     /** \relates Selectable More verbose stream output */
521     std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
522
523     /** Solvable to Selectable transform functor.
524      * \relates Selectable
525      * \relates sat::SolvIterMixin
526      */
527     struct asSelectable
528     {
529       typedef Selectable_Ptr result_type;
530
531       Selectable_Ptr operator()( const sat::Solvable & solv_r ) const;
532
533       Selectable_Ptr operator()( const PoolItem & pi_r ) const
534       { return operator()( pi_r.satSolvable() ); }
535     };
536
537     /////////////////////////////////////////////////////////////////
538   } // namespace ui
539   ///////////////////////////////////////////////////////////////////
540   /////////////////////////////////////////////////////////////////
541 } // namespace zypp
542 ///////////////////////////////////////////////////////////////////
543 #endif // ZYPP_UI_SELECTABLE_H