1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ui/SelectableImpl.h
12 #ifndef ZYPP_UI_SELECTABLEIMPL_H
13 #define ZYPP_UI_SELECTABLEIMPL_H
16 #include "zypp/base/LogTools.h"
18 #include "zypp/base/PtrTypes.h"
20 #include "zypp/ZConfig.h"
21 #include "zypp/ui/Selectable.h"
22 #include "zypp/ui/SelectableTraits.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////
35 // CLASS NAME : Selectable::Impl
37 /** Selectable implementation.
38 * \note Implementation is based in PoolItem, just the Selectable
39 * inteface restricts them to ResObject::constPtr.
41 struct Selectable::Impl
45 typedef SelectableTraits::AvailableItemSet AvailableItemSet;
46 typedef SelectableTraits::available_iterator available_iterator;
47 typedef SelectableTraits::available_const_iterator available_const_iterator;
48 typedef SelectableTraits::available_size_type available_size_type;
50 typedef SelectableTraits::InstalledItemSet InstalledItemSet;
51 typedef SelectableTraits::installed_iterator installed_iterator;
52 typedef SelectableTraits::installed_const_iterator installed_const_iterator;
53 typedef SelectableTraits::installed_size_type installed_size_type;
56 template <class _Iterator>
57 Impl( const ResObject::Kind & kind_r,
58 const std::string & name_r,
61 : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
65 for_( it, begin_r, end_r )
67 if ( it->status().isInstalled() )
68 _installedItems.insert( *it );
70 _availableItems.insert( *it );
72 _defaultCandidate = defaultCandidate();
77 IdString ident() const
81 ResObject::Kind kind() const
85 const std::string & name() const
89 Status status() const;
92 bool setStatus( const Status state_r, ResStatus::TransactByValue causer_r );
94 /** Installed object (transacting ot highest version). */
95 PoolItem installedObj() const
97 if ( installedEmpty() )
99 PoolItem ret( transactingInstalled() );
100 return ret ? ret : *_installedItems.begin();
103 /** Best among available objects.
104 * The transacting candidate or the one scheduled to receive
107 PoolItem candidateObj() const
109 PoolItem ret( transactingCandidate() );
112 return _candidate ? _candidate : _defaultCandidate;
115 /** Set a userCandidate (out of available objects).
116 * \return The new userCandidate or NULL if choice was invalid
117 * (not among availableObjs).
119 PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
121 /** The best candidate provided by a specific \ref Repository, if there is one.
122 * In contrary to \ref candidateObj, this may return no item even if
123 * there are available objects. This simply means the \ref Repository
124 * does not provide this object.
126 PoolItem candidateObjFrom( Repository repo_r ) const
128 for_( it, availableBegin(), availableEnd() )
130 if ( (*it)->repository() == repo_r )
136 /** The best candidate for update, if there is one.
137 * In contrary to \ref candidateObj, this may return no item even if
138 * there are available objects. This simply means the best object is
139 * already installed, and all available objects violate at least one
142 PoolItem updateCandidateObj() const
144 if ( multiversionInstall() || installedEmpty() || ! _defaultCandidate )
145 return _defaultCandidate;
146 // Here: installed and _defaultCandidate are non NULL and it's not a
147 // multiversion install.
149 // update candidate must come from the highest priority repo
150 if ( _defaultCandidate->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
153 PoolItem installed( installedObj() );
154 // check vendor change
155 if ( ! ( ZConfig::instance().solver_allowVendorChange()
156 || VendorAttr::instance().equivalent( _defaultCandidate->vendor(), installed->vendor() ) ) )
159 // check arch change (arch noarch changes are allowed)
160 if ( _defaultCandidate->arch() != installed->arch()
161 && ! ( _defaultCandidate->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
164 // check greater edition
165 if ( _defaultCandidate->edition() <= installed->edition() )
168 return _defaultCandidate;
171 /** \copydoc Selectable::highestAvailableVersionObj()const */
172 PoolItem highestAvailableVersionObj() const
175 for_( it, availableBegin(), availableEnd() )
177 if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
183 /** \copydoc Selectable::identicalAvailable( const PoolItem & )const */
184 bool identicalAvailable( const PoolItem & rhs ) const
186 if ( !availableEmpty() && rhs )
188 for_( it, _availableItems.begin(), _availableItems.end() )
190 if ( identical( *it, rhs ) )
197 /** \copydoc Selectable::identicalInstalled( const PoolItem & )const */
198 bool identicalInstalled( const PoolItem & rhs ) const
200 if ( !installedEmpty() && rhs )
202 for_( it, _installedItems.begin(), _installedItems.end() )
204 if ( identical( *it, rhs ) )
211 /** Best among all objects. */
212 PoolItem theObj() const
214 PoolItem ret( candidateObj() );
217 return installedObj();
220 ////////////////////////////////////////////////////////////////////////
222 bool availableEmpty() const
223 { return _availableItems.empty(); }
225 available_size_type availableSize() const
226 { return _availableItems.size(); }
228 available_const_iterator availableBegin() const
229 { return _availableItems.begin(); }
231 available_const_iterator availableEnd() const
232 { return _availableItems.end(); }
234 ////////////////////////////////////////////////////////////////////////
236 bool installedEmpty() const
237 { return _installedItems.empty(); }
239 installed_size_type installedSize() const
240 { return _installedItems.size(); }
242 installed_iterator installedBegin() const
243 { return _installedItems.begin(); }
245 installed_iterator installedEnd() const
246 { return _installedItems.end(); }
248 ////////////////////////////////////////////////////////////////////////
250 bool isUnmaintained() const
251 { return availableEmpty(); }
253 bool multiversionInstall() const
254 { return theObj().satSolvable().multiversionInstall(); }
256 bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
258 bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
260 ////////////////////////////////////////////////////////////////////////
262 bool isUndetermined() const
264 PoolItem cand( candidateObj() );
265 return ! cand || cand.isUndetermined();
267 bool isRelevant() const
269 PoolItem cand( candidateObj() );
270 return cand && cand.isRelevant();
272 bool isSatisfied() const
274 PoolItem cand( candidateObj() );
275 return cand && cand.isSatisfied();
277 bool isBroken() const
279 PoolItem cand( candidateObj() );
280 return cand && cand.isBroken();
283 /** Return who caused the modification. */
284 ResStatus::TransactByValue modifiedBy() const;
286 /** Return value of LicenceConfirmed bit. */
287 bool hasLicenceConfirmed() const
288 { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
290 /** Set LicenceConfirmed bit. */
291 void setLicenceConfirmed( bool val_r )
292 { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
295 PoolItem transactingInstalled() const
297 for_( it, installedBegin(), installedEnd() )
299 if ( (*it).status().transacts() )
305 PoolItem transactingCandidate() const
307 for_( it, availableBegin(), availableEnd() )
309 if ( (*it).status().transacts() )
315 PoolItem defaultCandidate() const
317 if ( ! ( multiversionInstall() || installedEmpty() ) )
319 // prefer the installed objects arch and vendor
320 bool solver_allowVendorChange( ZConfig::instance().solver_allowVendorChange() );
321 for ( installed_const_iterator iit = installedBegin();
322 iit != installedEnd(); ++iit )
324 PoolItem sameArch; // in case there's no same vendor at least stay with same arch.
325 for ( available_const_iterator it = availableBegin();
326 it != availableEnd(); ++it )
328 // 'same arch' includes allowed changes to/from noarch.
329 if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
331 if ( ! solver_allowVendorChange )
333 if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
335 else if ( ! sameArch ) // remember best same arch in case no same vendor found
338 else // same arch is sufficient
346 if ( _availableItems.empty() )
349 return *_availableItems.begin();
352 bool allCandidatesLocked() const
354 for ( available_const_iterator it = availableBegin();
355 it != availableEnd(); ++it )
357 if ( ! (*it).status().isLocked() )
360 return( ! _availableItems.empty() );
364 const IdString _ident;
365 const ResObject::Kind _kind;
366 const std::string _name;
367 InstalledItemSet _installedItems;
368 AvailableItemSet _availableItems;
369 //! Best among availabe with restpect to installed.
370 PoolItem _defaultCandidate;
372 //! The object selected by setCandidateObj() method.
375 ///////////////////////////////////////////////////////////////////
377 /** \relates Selectable::Impl Stream output */
378 inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
380 return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
381 << " (I " << obj.installedSize() << ")"
382 << " (A " << obj.availableSize() << ")"
383 << obj.candidateObj();
386 /** \relates Selectable::Impl Stream output */
387 inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
389 str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
390 << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
392 if ( obj.installedEmpty() )
393 str << " (I 0) {}" << endl << " ";
396 PoolItem icand( obj.installedObj() );
397 str << " (I " << obj.installedSize() << ") {" << endl;
398 for_( it, obj.installedBegin(), obj.installedEnd() )
405 str << " " << t << " " << *it << endl;
410 if ( obj.availableEmpty() )
416 PoolItem cand( obj.candidateObj() );
417 PoolItem up( obj.updateCandidateObj() );
418 str << "(A " << obj.availableSize() << ") {" << endl;
419 for_( it, obj.availableBegin(), obj.availableEnd() )
424 t = *it == up ? 'C' : 'c';
426 else if ( *it == up )
430 str << " " << t << " " << *it << endl;
437 /////////////////////////////////////////////////////////////////
439 ///////////////////////////////////////////////////////////////////
440 /////////////////////////////////////////////////////////////////
442 ///////////////////////////////////////////////////////////////////
443 #endif // ZYPP_UI_SELECTABLEIMPL_H