1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ui/Selectable.h
12 #ifndef ZYPP_UI_SELECTABLE_H
13 #define ZYPP_UI_SELECTABLE_H
17 #include "zypp/base/ReferenceCounted.h"
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Iterator.h"
22 #include "zypp/ui/SelectableTraits.h"
23 #include "zypp/ui/Status.h"
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 DEFINE_PTR_TYPE(Selectable);
35 ///////////////////////////////////////////////////////////////////
37 // CLASS NAME : Selectable
39 /** Collects PoolItems of same kind and name.
41 * Selectable is a status wrapper. The ui::Status is calculated
42 * from (and transated to) \ref PoolItems individual \ref ResStatus
45 * Available objects are sorted according the solver policies, 'best'
46 * packages first (e.g. by repository priority, then Arch, then Edition).
48 * Installed objects are sorted according the installation date, newer install
51 class Selectable : public base::ReferenceCounted, private base::NonCopyable
53 friend std::ostream & operator<<( std::ostream & str, const Selectable & obj );
54 friend std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
57 typedef intrusive_ptr<Selectable> Ptr;
58 typedef intrusive_ptr<const Selectable> constPtr;
60 /** Iterates over ResObject::constPtr */
61 typedef SelectableTraits::available_iterator available_iterator;
62 typedef SelectableTraits::available_size_type available_size_type;
64 typedef SelectableTraits::installed_iterator installed_iterator;
65 typedef SelectableTraits::installed_size_type installed_size_type;
67 typedef SelectableTraits::picklist_iterator picklist_iterator;
68 typedef SelectableTraits::picklist_size_type picklist_size_type;
71 /** \name Static ctor substitues picking the item from the pool.
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
80 /** Get the \ref Selctable */
81 static Ptr get( const pool::ByIdent & ident_r );
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 ) ); }
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 ) ); }
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 ) ); }
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 ) ); }
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(); }
103 /** Get the \ref Selctable containing a specific \ref PoolItem. */
104 static Ptr get( const PoolItem & pi_r )
105 { return get( pi_r.satSolvable() ); }
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.
114 IdString ident() const;
116 /** The ResObjects kind. */
117 ResKind kind() const;
119 /** The ResObjects name. */
120 const std::string & name() const;
122 /** The last Installed object. */
123 PoolItem installedObj() const;
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).
129 PoolItem candidateObj() const;
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.
136 PoolItem candidateObjFrom( Repository repo_r ) const;
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
144 PoolItem updateCandidateObj() const;
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.
151 PoolItem highestAvailableVersionObj() const;
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
157 bool identicalAvailable( const PoolItem & rhs ) const;
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
163 bool identicalInstalled( const PoolItem & rhs ) const;
165 /** \c True if the \ref candidateObj is installed (same content).
166 * \see \ref identicalInstalled.
168 bool identicalInstalledCandidate() const
169 { return identicalInstalled( candidateObj() ); }
171 /** \c True if the \ref updateCandidateObj is installed (same content).
172 * \see \ref identicalInstalled.
174 bool identicalInstalledUpdateCandidate() const
175 { return identicalInstalled( updateCandidateObj() ); }
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
181 PoolItem identicalAvailableObj( const PoolItem & rhs ) const;
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
187 PoolItem identicalInstalledObj( const PoolItem & rhs ) const;
189 /** Return the \ref installedObj resolvable casted to a specific kind.
191 * Selectable mySelectable;
192 * Package::constPtr p( mySelectable.installedAsKind<Package>() );
196 typename ResTraits<_Res>::constPtrType installedAsKind() const
197 { return asKind<_Res>( candidateObj() ); }
199 /** Return the \ref candidateObj resolvable casted to a specific kind.
201 * Selectable mySelectable;
202 * Package::constPtr p( mySelectable.candidateAsKind<Package>() );
206 typename ResTraits<_Res>::constPtrType candidateAsKind() const
207 { return asKind<_Res>( candidateObj() ); }
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.
217 PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
219 PoolItem setCandidate( ResObject::constPtr newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
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.
227 bool setOnSystem( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
229 /** An object you could use as pars pro toto.
231 * \return the \ref candidateObj, or ,if no available objects
232 * exist, the \ref installedObj.
234 PoolItem theObj() const;
236 ////////////////////////////////////////////////////////////////////////
238 /** \name Available objects iterators.
239 * Oredered according to solver policy. 'Best' first.
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() ); }
250 ////////////////////////////////////////////////////////////////////////
252 /** \name Installed objects iterators.
253 * Ordered by install time. Latest first.
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() ); }
264 ////////////////////////////////////////////////////////////////////////
266 /** \name picklist iterators.
267 * This is basically the available items list prepended by those
268 * installed items, that are nolonger \ref identicalAvailable.
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() ); }
279 ////////////////////////////////////////////////////////////////////////
282 /** \name Query for objects within this Selectable.
285 /** True if either installed or candidate object is present */
286 bool hasObject() const
287 { return (! installedEmpty()) || candidateObj(); }
289 /** True if installed object is present. */
290 bool hasInstalledObj() const
291 { return ! installedEmpty(); }
293 /** True if candidate object is present. */
294 bool hasCandidateObj() const
295 { return bool(candidateObj()); }
297 /** True if installed and candidate object is present */
298 bool hasBothObjects() const
299 { return (! installedEmpty()) && candidateObj(); }
301 /** True if installed object is present but no candidate. */
302 bool hasInstalledObjOnly() const
303 { return (! installedEmpty()) && ! candidateObj(); }
305 /** True if candidate object is present but no installed. */
306 bool hasCandidateObjOnly() const
307 { return ( installedEmpty() ) && candidateObj(); }
311 * True if this package has no replacement from
312 * the available repositories
314 bool isUnmaintained() const;
316 /** \name Multiversion install.
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.
323 /** Whether at least one of the available packages has multiversionInstall set.
324 * \see \ref Solvable::multiversionInstall
325 * \see also \ref ZConfig::multiversion.
327 bool multiversionInstall() const;
329 /** Select a specific available item for installation.
331 bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
333 /** Deselect a specific available item from installation.
335 bool pickNoInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
336 { return pickInstall( pi_r, causer_r, false ); }
338 /** Select a specific installed item for deletion.
340 bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
342 /** Deselect a specific installed item from deletion.
344 bool pickNoDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
345 { return pickDelete( pi_r, causer_r, false ); }
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.
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)':
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
360 * After 'foo-1.1 (vendor A) (repo 1)' was selected to be installed:
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
368 * \see \ref sat::Solvable::identical
370 Status pickStatus( const PoolItem & pi_r ) const;
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 );
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
382 /** Returns true for packages, because packages are not
383 * classified by the solver.
385 bool isUndetermined() const;
387 /** Returns true if the patch is relevant which means that at least
388 * one package of the patch is installed.
390 bool isRelevant() const;
392 /** Whether a relevant patchs requirements are met. */
393 bool isSatisfied() const;
395 /** Whether a relevant patchs requirements are broken. */
396 bool isBroken() const;
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.
403 bool isNeeded() const;
405 /** Broken (needed) but locked patches. */
406 bool isUnwanted() const;
410 /** \name Query and maip objects fate in case of commit.
421 /** True if neither to delete or to install */
422 bool unmodified() const
423 { return fate() == UNMODIFIED; }
425 /** True if locked (subclass of unmodified). */
427 { Status st( status() ); return( st == S_Protected || st == S_Taboo ); }
429 /** True if either to delete or to install */
430 bool toModify() const
431 { return fate() != UNMODIFIED; }
433 /** True if to delete */
434 bool toDelete() const
435 { return fate() == TO_DELETE; }
437 /** True if to install */
438 bool toInstall() const
439 { return fate() == TO_INSTALL; }
441 /** True if would be on system after commit. */
442 bool onSystem() const
443 { return( ( hasInstalledObj() && !toDelete() )
444 ||( hasCandidateObj() && toInstall() ) ); }
446 /** True if would be off system after commit. */
447 bool offSystem() const
448 { return ! onSystem(); }
451 bool setFate( Fate fate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
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 ); }
457 /** Take care the item gets installed if it is not. */
458 bool setInstalled( ResStatus::TransactByValue causer_r = ResStatus::USER );
460 /** Take care the item gets installed if it is not, or is older. */
461 bool setUpToDate( ResStatus::TransactByValue causer_r = ResStatus::USER );
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 ); }
467 /** Take care the item gets deleted if it is installed. */
468 bool setDeleted( ResStatus::TransactByValue causer_r = ResStatus::USER );
470 /** Set the item to stay unmodified. */
471 bool unset( ResStatus::TransactByValue causer_r = ResStatus::USER )
472 { return setFate( UNMODIFIED, causer_r ); }
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.
483 /** Return the current Status */
484 Status status() const;
487 * Try to set a new Status.
488 * Returns \c false if the transitions is not allowed.
490 bool setStatus( Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
492 /** Return who caused the modification. */
493 ResStatus::TransactByValue modifiedBy() const;
495 /** Return value of LicenceConfirmed bit. */
496 bool hasLicenceConfirmed() const;
498 /** Set LicenceConfirmed bit. */
499 void setLicenceConfirmed( bool val_r = true );
503 /** Implementation */
505 typedef shared_ptr<Impl> Impl_Ptr;
507 Selectable( Impl_Ptr pimpl_r );
512 /** Pointer to implementation */
513 RW_pointer<Impl> _pimpl;
515 ///////////////////////////////////////////////////////////////////
517 /** \relates Selectable Stream output */
518 std::ostream & operator<<( std::ostream & str, const Selectable & obj );
520 /** \relates Selectable More verbose stream output */
521 std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
523 /** Solvable to Selectable transform functor.
524 * \relates Selectable
525 * \relates sat::SolvIterMixin
529 typedef Selectable_Ptr result_type;
531 Selectable_Ptr operator()( const sat::Solvable & solv_r ) const;
533 Selectable_Ptr operator()( const PoolItem & pi_r ) const
534 { return operator()( pi_r.satSolvable() ); }
537 /////////////////////////////////////////////////////////////////
539 ///////////////////////////////////////////////////////////////////
540 /////////////////////////////////////////////////////////////////
542 ///////////////////////////////////////////////////////////////////
543 #endif // ZYPP_UI_SELECTABLE_H