SelectableImpl.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_UI_SELECTABLEIMPL_H
00013 #define ZYPP_UI_SELECTABLEIMPL_H
00014
00015 #include <iostream>
00016 #include "zypp/base/LogTools.h"
00017
00018 #include "zypp/base/PtrTypes.h"
00019
00020 #include "zypp/ZConfig.h"
00021 #include "zypp/ui/Selectable.h"
00022 #include "zypp/ui/SelectableTraits.h"
00023
00024 using std::endl;
00025
00027 namespace zypp
00028 {
00029
00030 namespace ui
00031 {
00032
00034
00035
00036
00041 struct Selectable::Impl
00042 {
00043 public:
00044
00045 typedef SelectableTraits::AvailableItemSet AvailableItemSet;
00046 typedef SelectableTraits::available_iterator available_iterator;
00047 typedef SelectableTraits::available_const_iterator available_const_iterator;
00048 typedef SelectableTraits::available_size_type available_size_type;
00049
00050 typedef SelectableTraits::InstalledItemSet InstalledItemSet;
00051 typedef SelectableTraits::installed_iterator installed_iterator;
00052 typedef SelectableTraits::installed_const_iterator installed_const_iterator;
00053 typedef SelectableTraits::installed_size_type installed_size_type;
00054
00055 typedef SelectableTraits::PickList PickList;
00056
00057 public:
00058 template <class _Iterator>
00059 Impl( const ResObject::Kind & kind_r,
00060 const std::string & name_r,
00061 _Iterator begin_r,
00062 _Iterator end_r )
00063 : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
00064 , _kind( kind_r )
00065 , _name( name_r )
00066 {
00067 for_( it, begin_r, end_r )
00068 {
00069 if ( it->status().isInstalled() )
00070 _installedItems.insert( *it );
00071 else
00072 _availableItems.insert( *it );
00073 }
00074 _defaultCandidate = defaultCandidate();
00075 }
00076
00077 public:
00079 IdString ident() const
00080 { return _ident; }
00081
00083 ResObject::Kind kind() const
00084 { return _kind; }
00085
00087 const std::string & name() const
00088 { return _name; }
00089
00091 Status status() const;
00092
00094 bool setStatus( Status state_r, ResStatus::TransactByValue causer_r );
00095
00097 PoolItem installedObj() const
00098 {
00099 if ( installedEmpty() )
00100 return PoolItem();
00101 PoolItem ret( transactingInstalled() );
00102 return ret ? ret : *_installedItems.begin();
00103 }
00104
00109 PoolItem candidateObj() const
00110 {
00111 PoolItem ret( transactingCandidate() );
00112 if ( ret )
00113 return ret;
00114 return _candidate ? _candidate : _defaultCandidate;
00115 }
00116
00121 PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
00122
00128 PoolItem candidateObjFrom( Repository repo_r ) const
00129 {
00130 for_( it, availableBegin(), availableEnd() )
00131 {
00132 if ( (*it)->repository() == repo_r )
00133 return *it;
00134 }
00135 return PoolItem();
00136 }
00137
00144 PoolItem updateCandidateObj() const
00145 {
00146 if ( multiversionInstall() || installedEmpty() || ! _defaultCandidate )
00147 return _defaultCandidate;
00148
00149
00150
00151
00152 if ( _defaultCandidate->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
00153 return PoolItem();
00154
00155 PoolItem installed( installedObj() );
00156
00157 if ( ! ( ZConfig::instance().solver_allowVendorChange()
00158 || VendorAttr::instance().equivalent( _defaultCandidate->vendor(), installed->vendor() ) ) )
00159 return PoolItem();
00160
00161
00162 if ( _defaultCandidate->arch() != installed->arch()
00163 && ! ( _defaultCandidate->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
00164 return PoolItem();
00165
00166
00167 if ( _defaultCandidate->edition() <= installed->edition() )
00168 return PoolItem();
00169
00170 return _defaultCandidate;
00171 }
00172
00174 PoolItem highestAvailableVersionObj() const
00175 {
00176 PoolItem ret;
00177 for_( it, availableBegin(), availableEnd() )
00178 {
00179 if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
00180 ret = *it;
00181 }
00182 return ret;
00183 }
00184
00186 bool identicalAvailable( const PoolItem & rhs ) const
00187 {
00188 if ( !availableEmpty() && rhs )
00189 {
00190 for_( it, _availableItems.begin(), _availableItems.end() )
00191 {
00192 if ( identical( *it, rhs ) )
00193 return true;
00194 }
00195 }
00196 return false;
00197 }
00198
00200 bool identicalInstalled( const PoolItem & rhs ) const
00201 {
00202 if ( !installedEmpty() && rhs )
00203 {
00204 for_( it, _installedItems.begin(), _installedItems.end() )
00205 {
00206 if ( identical( *it, rhs ) )
00207 return true;
00208 }
00209 }
00210 return false;
00211 }
00212
00214 PoolItem theObj() const
00215 {
00216 PoolItem ret( candidateObj() );
00217 if ( ret )
00218 return ret;
00219 return installedObj();
00220 }
00221
00223
00224 bool availableEmpty() const
00225 { return _availableItems.empty(); }
00226
00227 available_size_type availableSize() const
00228 { return _availableItems.size(); }
00229
00230 available_const_iterator availableBegin() const
00231 { return _availableItems.begin(); }
00232
00233 available_const_iterator availableEnd() const
00234 { return _availableItems.end(); }
00235
00237
00238 bool installedEmpty() const
00239 { return _installedItems.empty(); }
00240
00241 installed_size_type installedSize() const
00242 { return _installedItems.size(); }
00243
00244 installed_iterator installedBegin() const
00245 { return _installedItems.begin(); }
00246
00247 installed_iterator installedEnd() const
00248 { return _installedItems.end(); }
00249
00251
00252 const PickList & picklist() const
00253 {
00254 if ( ! _picklistPtr )
00255 {
00256 _picklistPtr.reset( new PickList );
00257
00258 for_( it, _installedItems.begin(), _installedItems.end() )
00259 {
00260 if ( ! identicalAvailable( *it ) )
00261 _picklistPtr->push_back( *it );
00262 }
00263 _picklistPtr->insert( _picklistPtr->end(), availableBegin(), availableEnd() );
00264 }
00265 return *_picklistPtr;
00266 }
00267
00268 bool picklistEmpty() const
00269 { return picklist().empty(); }
00270
00271 picklist_size_type picklistSize() const
00272 { return picklist().size(); }
00273
00274 picklist_iterator picklistBegin() const
00275 { return picklist().begin(); }
00276
00277 picklist_iterator picklistEnd() const
00278 { return picklist().end(); }
00279
00281
00282 bool isUnmaintained() const
00283 { return availableEmpty(); }
00284
00285 bool multiversionInstall() const
00286 { return theObj().satSolvable().multiversionInstall(); }
00287
00288 bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
00289
00290 bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
00291
00292 Status pickStatus( const PoolItem & pi_r ) const;
00293
00294 bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r );
00295
00297
00298 bool isUndetermined() const
00299 {
00300 PoolItem cand( candidateObj() );
00301 return ! cand || cand.isUndetermined();
00302 }
00303 bool isRelevant() const
00304 {
00305 PoolItem cand( candidateObj() );
00306 return cand && cand.isRelevant();
00307 }
00308 bool isSatisfied() const
00309 {
00310 PoolItem cand( candidateObj() );
00311 return cand && cand.isSatisfied();
00312 }
00313 bool isBroken() const
00314 {
00315 PoolItem cand( candidateObj() );
00316 return cand && cand.isBroken();
00317 }
00318
00320 ResStatus::TransactByValue modifiedBy() const;
00321
00323 bool hasLicenceConfirmed() const
00324 { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
00325
00327 void setLicenceConfirmed( bool val_r )
00328 { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
00329
00330 private:
00331 PoolItem transactingInstalled() const
00332 {
00333 for_( it, installedBegin(), installedEnd() )
00334 {
00335 if ( (*it).status().transacts() )
00336 return (*it);
00337 }
00338 return PoolItem();
00339 }
00340
00341 PoolItem transactingCandidate() const
00342 {
00343 for_( it, availableBegin(), availableEnd() )
00344 {
00345 if ( (*it).status().transacts() )
00346 return (*it);
00347 }
00348 return PoolItem();
00349 }
00350
00351 PoolItem defaultCandidate() const
00352 {
00353 if ( ! ( multiversionInstall() || installedEmpty() ) )
00354 {
00355
00356 bool solver_allowVendorChange( ZConfig::instance().solver_allowVendorChange() );
00357 for ( installed_const_iterator iit = installedBegin();
00358 iit != installedEnd(); ++iit )
00359 {
00360 PoolItem sameArch;
00361 for ( available_const_iterator it = availableBegin();
00362 it != availableEnd(); ++it )
00363 {
00364
00365 if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
00366 {
00367 if ( ! solver_allowVendorChange )
00368 {
00369 if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
00370 return *it;
00371 else if ( ! sameArch )
00372 sameArch = *it;
00373 }
00374 else
00375 return *it;
00376 }
00377 }
00378 if ( sameArch )
00379 return sameArch;
00380 }
00381 }
00382 if ( _availableItems.empty() )
00383 return PoolItem();
00384
00385 return *_availableItems.begin();
00386 }
00387
00388 bool allCandidatesLocked() const
00389 {
00390 for ( available_const_iterator it = availableBegin();
00391 it != availableEnd(); ++it )
00392 {
00393 if ( ! (*it).status().isLocked() )
00394 return false;
00395 }
00396 return( ! _availableItems.empty() );
00397 }
00398
00399 bool allInstalledLocked() const
00400 {
00401 for ( installed_const_iterator it = installedBegin();
00402 it != installedEnd(); ++it )
00403 {
00404 if ( ! (*it).status().isLocked() )
00405 return false;
00406 }
00407 return( ! _installedItems.empty() );
00408 }
00409
00410
00411 private:
00412 const IdString _ident;
00413 const ResObject::Kind _kind;
00414 const std::string _name;
00415 InstalledItemSet _installedItems;
00416 AvailableItemSet _availableItems;
00418 PoolItem _defaultCandidate;
00420 PoolItem _candidate;
00422 mutable scoped_ptr<PickList> _picklistPtr;
00423 };
00425
00427 inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
00428 {
00429 return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
00430 << " (I " << obj.installedSize() << ")"
00431 << " (A " << obj.availableSize() << ")"
00432 << obj.candidateObj();
00433 }
00434
00436 inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
00437 {
00438 str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
00439 << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
00440
00441 if ( obj.installedEmpty() )
00442 str << " (I 0) {}" << endl << " ";
00443 else
00444 {
00445 PoolItem icand( obj.installedObj() );
00446 str << " (I " << obj.installedSize() << ") {" << endl;
00447 for_( it, obj.installedBegin(), obj.installedEnd() )
00448 {
00449 char t = ' ';
00450 if ( *it == icand )
00451 {
00452 t = 'i';
00453 }
00454 str << " " << t << " " << *it << endl;
00455 }
00456 str << "} ";
00457 }
00458
00459 if ( obj.availableEmpty() )
00460 {
00461 str << "(A 0) {}" << endl << " ";
00462 }
00463 else
00464 {
00465 PoolItem cand( obj.candidateObj() );
00466 PoolItem up( obj.updateCandidateObj() );
00467 str << "(A " << obj.availableSize() << ") {" << endl;
00468 for_( it, obj.availableBegin(), obj.availableEnd() )
00469 {
00470 char t = ' ';
00471 if ( *it == cand )
00472 {
00473 t = *it == up ? 'C' : 'c';
00474 }
00475 else if ( *it == up )
00476 {
00477 t = 'u';
00478 }
00479 str << " " << t << " " << *it << endl;
00480 }
00481 str << "} ";
00482 }
00483
00484 if ( obj.picklistEmpty() )
00485 {
00486 str << "(P 0) {}";
00487 }
00488 else
00489 {
00490 PoolItem cand( obj.candidateObj() );
00491 PoolItem up( obj.updateCandidateObj() );
00492 str << "(P " << obj.picklistSize() << ") {" << endl;
00493 for_( it, obj.picklistBegin(), obj.picklistEnd() )
00494 {
00495 char t = ' ';
00496 if ( *it == cand )
00497 {
00498 t = *it == up ? 'C' : 'c';
00499 }
00500 else if ( *it == up )
00501 {
00502 t = 'u';
00503 }
00504 str << " " << t << " " << *it << "\t" << obj.pickStatus( *it ) << endl;
00505 }
00506 str << "} ";
00507 }
00508
00509 return str;
00510 }
00512 }
00515 }
00517 #endif // ZYPP_UI_SELECTABLEIMPL_H