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;
55 typedef SelectableTraits::PickList PickList;
58 template <class _Iterator>
59 Impl( const ResObject::Kind & kind_r,
60 const std::string & name_r,
63 : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
67 for_( it, begin_r, end_r )
69 if ( it->status().isInstalled() )
70 _installedItems.insert( *it );
72 _availableItems.insert( *it );
74 _defaultCandidate = defaultCandidate();
79 IdString ident() const
83 ResObject::Kind kind() const
87 const std::string & name() const
91 Status status() const;
94 bool setStatus( const Status state_r, ResStatus::TransactByValue causer_r );
96 /** Installed object (transacting ot highest version). */
97 PoolItem installedObj() const
99 if ( installedEmpty() )
101 PoolItem ret( transactingInstalled() );
102 return ret ? ret : *_installedItems.begin();
105 /** Best among available objects.
106 * The transacting candidate or the one scheduled to receive
109 PoolItem candidateObj() const
111 PoolItem ret( transactingCandidate() );
114 return _candidate ? _candidate : _defaultCandidate;
117 /** Set a userCandidate (out of available objects).
118 * \return The new userCandidate or NULL if choice was invalid
119 * (not among availableObjs).
121 PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
123 /** The best candidate provided by a specific \ref Repository, if there is one.
124 * In contrary to \ref candidateObj, this may return no item even if
125 * there are available objects. This simply means the \ref Repository
126 * does not provide this object.
128 PoolItem candidateObjFrom( Repository repo_r ) const
130 for_( it, availableBegin(), availableEnd() )
132 if ( (*it)->repository() == repo_r )
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 if ( multiversionInstall() || installedEmpty() || ! _defaultCandidate )
147 return _defaultCandidate;
148 // Here: installed and _defaultCandidate are non NULL and it's not a
149 // multiversion install.
151 // update candidate must come from the highest priority repo
152 if ( _defaultCandidate->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
155 PoolItem installed( installedObj() );
156 // check vendor change
157 if ( ! ( ZConfig::instance().solver_allowVendorChange()
158 || VendorAttr::instance().equivalent( _defaultCandidate->vendor(), installed->vendor() ) ) )
161 // check arch change (arch noarch changes are allowed)
162 if ( _defaultCandidate->arch() != installed->arch()
163 && ! ( _defaultCandidate->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
166 // check greater edition
167 if ( _defaultCandidate->edition() <= installed->edition() )
170 return _defaultCandidate;
173 /** \copydoc Selectable::highestAvailableVersionObj()const */
174 PoolItem highestAvailableVersionObj() const
177 for_( it, availableBegin(), availableEnd() )
179 if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
185 /** \copydoc Selectable::identicalAvailable( const PoolItem & )const */
186 bool identicalAvailable( const PoolItem & rhs ) const
188 if ( !availableEmpty() && rhs )
190 for_( it, _availableItems.begin(), _availableItems.end() )
192 if ( identical( *it, rhs ) )
199 /** \copydoc Selectable::identicalInstalled( const PoolItem & )const */
200 bool identicalInstalled( const PoolItem & rhs ) const
202 if ( !installedEmpty() && rhs )
204 for_( it, _installedItems.begin(), _installedItems.end() )
206 if ( identical( *it, rhs ) )
213 /** Best among all objects. */
214 PoolItem theObj() const
216 PoolItem ret( candidateObj() );
219 return installedObj();
222 ////////////////////////////////////////////////////////////////////////
224 bool availableEmpty() const
225 { return _availableItems.empty(); }
227 available_size_type availableSize() const
228 { return _availableItems.size(); }
230 available_const_iterator availableBegin() const
231 { return _availableItems.begin(); }
233 available_const_iterator availableEnd() const
234 { return _availableItems.end(); }
236 ////////////////////////////////////////////////////////////////////////
238 bool installedEmpty() const
239 { return _installedItems.empty(); }
241 installed_size_type installedSize() const
242 { return _installedItems.size(); }
244 installed_iterator installedBegin() const
245 { return _installedItems.begin(); }
247 installed_iterator installedEnd() const
248 { return _installedItems.end(); }
250 ////////////////////////////////////////////////////////////////////////
252 const PickList & picklist() const
254 if ( ! _picklistPtr )
256 _picklistPtr.reset( new PickList( _availableItems.size() ) );
257 // installed without identical avaialble first:
258 for_( it, _installedItems.begin(), _installedItems.end() )
260 if ( ! identicalAvailable( *it ) )
261 _picklistPtr->push_back( *it );
263 _picklistPtr->insert( _picklistPtr->end(), availableBegin(), availableEnd() );
265 return *_picklistPtr;
268 bool picklistEmpty() const
269 { return picklist().empty(); }
271 picklist_size_type picklistSize() const
272 { return picklist().size(); }
274 picklist_iterator picklistBegin() const
275 { return picklist().begin(); }
277 picklist_iterator picklistEnd() const
278 { return picklist().end(); }
280 ////////////////////////////////////////////////////////////////////////
282 bool isUnmaintained() const
283 { return availableEmpty(); }
285 bool multiversionInstall() const
286 { return theObj().satSolvable().multiversionInstall(); }
288 bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
290 bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
292 Status pickStatus( const PoolItem & pi_r ) const;
294 ////////////////////////////////////////////////////////////////////////
296 bool isUndetermined() const
298 PoolItem cand( candidateObj() );
299 return ! cand || cand.isUndetermined();
301 bool isRelevant() const
303 PoolItem cand( candidateObj() );
304 return cand && cand.isRelevant();
306 bool isSatisfied() const
308 PoolItem cand( candidateObj() );
309 return cand && cand.isSatisfied();
311 bool isBroken() const
313 PoolItem cand( candidateObj() );
314 return cand && cand.isBroken();
317 /** Return who caused the modification. */
318 ResStatus::TransactByValue modifiedBy() const;
320 /** Return value of LicenceConfirmed bit. */
321 bool hasLicenceConfirmed() const
322 { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
324 /** Set LicenceConfirmed bit. */
325 void setLicenceConfirmed( bool val_r )
326 { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
329 PoolItem transactingInstalled() const
331 for_( it, installedBegin(), installedEnd() )
333 if ( (*it).status().transacts() )
339 PoolItem transactingCandidate() const
341 for_( it, availableBegin(), availableEnd() )
343 if ( (*it).status().transacts() )
349 PoolItem defaultCandidate() const
351 if ( ! ( multiversionInstall() || installedEmpty() ) )
353 // prefer the installed objects arch and vendor
354 bool solver_allowVendorChange( ZConfig::instance().solver_allowVendorChange() );
355 for ( installed_const_iterator iit = installedBegin();
356 iit != installedEnd(); ++iit )
358 PoolItem sameArch; // in case there's no same vendor at least stay with same arch.
359 for ( available_const_iterator it = availableBegin();
360 it != availableEnd(); ++it )
362 // 'same arch' includes allowed changes to/from noarch.
363 if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
365 if ( ! solver_allowVendorChange )
367 if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
369 else if ( ! sameArch ) // remember best same arch in case no same vendor found
372 else // same arch is sufficient
380 if ( _availableItems.empty() )
383 return *_availableItems.begin();
386 bool allCandidatesLocked() const
388 for ( available_const_iterator it = availableBegin();
389 it != availableEnd(); ++it )
391 if ( ! (*it).status().isLocked() )
394 return( ! _availableItems.empty() );
398 const IdString _ident;
399 const ResObject::Kind _kind;
400 const std::string _name;
401 InstalledItemSet _installedItems;
402 AvailableItemSet _availableItems;
403 //! Best among availabe with restpect to installed.
404 PoolItem _defaultCandidate;
405 //! The object selected by setCandidateObj() method.
407 //! lazy initialized picklist
408 mutable scoped_ptr<PickList> _picklistPtr;
410 ///////////////////////////////////////////////////////////////////
412 /** \relates Selectable::Impl Stream output */
413 inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
415 return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
416 << " (I " << obj.installedSize() << ")"
417 << " (A " << obj.availableSize() << ")"
418 << obj.candidateObj();
421 /** \relates Selectable::Impl Stream output */
422 inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
424 str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
425 << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
427 if ( obj.installedEmpty() )
428 str << " (I 0) {}" << endl << " ";
431 PoolItem icand( obj.installedObj() );
432 str << " (I " << obj.installedSize() << ") {" << endl;
433 for_( it, obj.installedBegin(), obj.installedEnd() )
440 str << " " << t << " " << *it << endl;
445 if ( obj.availableEmpty() )
451 PoolItem cand( obj.candidateObj() );
452 PoolItem up( obj.updateCandidateObj() );
453 str << "(A " << obj.availableSize() << ") {" << endl;
454 for_( it, obj.availableBegin(), obj.availableEnd() )
459 t = *it == up ? 'C' : 'c';
461 else if ( *it == up )
465 str << " " << t << " " << *it << endl;
472 /////////////////////////////////////////////////////////////////
474 ///////////////////////////////////////////////////////////////////
475 /////////////////////////////////////////////////////////////////
477 ///////////////////////////////////////////////////////////////////
478 #endif // ZYPP_UI_SELECTABLEIMPL_H