00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef PMSelectable_h
00020 #define PMSelectable_h
00021
00022 #include <iosfwd>
00023 #include <list>
00024
00025 #include <y2pm/PMSelectablePtr.h>
00026
00027 #include <y2pm/PMTypes.h>
00028 #include <y2pm/SelState.h>
00029 #include <y2pm/PkgName.h>
00030 #include <y2pm/PkgArch.h>
00031 #include <y2pm/PMObjectPtr.h>
00032
00033 class PMManager;
00034 class SavedState;
00035
00037
00038
00042 class PMSelectable : public CountedRep {
00043 REP_BODY(PMSelectable);
00044
00045 public:
00046
00047 typedef std::list<PMObjectPtr> PMObjectList;
00048
00049 class SavedState {
00050 public:
00051 SavedState() {}
00052 private:
00053 friend class PMManager;
00054
00055 PMSelectablePtr _item;
00056 SelState _state;
00057 PMObjectPtr _userCandidateObj;
00058
00059 SavedState( const PMSelectablePtr & item_r );
00060 bool mayReplay() const;
00061 bool replay();
00062 bool diff() const;
00063 };
00064
00065 private:
00066
00067 friend class Y2PM;
00068 static bool setCandidateOrder( PM::CandidateOrder neworder_r );
00069
00070 typedef bool (*ClistCompare)( const PMObjectPtr & lhs, const PMObjectPtr & rhs );
00071
00072 static ClistCompare _clistCompare;
00073
00074 static bool clistAVS( const PMObjectPtr & lhs, const PMObjectPtr & rhs );
00075
00076 static bool clistASV( const PMObjectPtr & lhs, const PMObjectPtr & rhs );
00077
00078 private:
00079
00080 friend class PMManager;
00081 friend class SavedState;
00082
00083 PMManager * _manager;
00084 SelState _state;
00085
00086 void _mgr_attach( PMManager * mgr_r );
00087 void _mgr_detach();
00088
00089 void _attach_obj( PMObjectPtr & obj_r );
00090 void _detach_obj( PMObjectPtr & obj_r );
00091
00092 void setInstalledObj( PMObjectPtr obj_r );
00093 void delInstalledObj() { setInstalledObj( PMObjectPtr() ); }
00094
00095 static bool clistIsBetter( const PMObjectPtr & lhs, const PMObjectPtr & rhs );
00096 void clistAdd( PMObjectPtr obj_r );
00097 void clistDel( PMObjectPtr obj_r );
00098 void clistSort();
00099 void clistClearAll();
00100
00101 void clearAll();
00102
00103 bool isEmpty() const;
00104
00105 void check() const;
00106
00107 private:
00108
00109 PkgName _name;
00110
00111 PMObjectPtr _installedObj;
00112 PMObjectPtr _candidateObj;
00113 PMObjectPtr _userCandidateObj;
00114
00115 PMObjectList _candidateList;
00116
00117 PMObjectList::iterator clistLookup( PMObjectPtr obj_r );
00118
00119 void chooseCandidateObj();
00120 void clearCandidateObj();
00121
00122 private:
00123
00124 typedef void (PMManager::*SelectableNotify)( constPMSelectablePtr item_r, SelState old_r, SelState new_r );
00125
00126
00127
00128 struct ObservedSelState {
00129 const PMSelectable * _item;
00130 SelState & _cstate;
00131 PMManager *& _mgr;
00132 SelectableNotify _notifyFnc;
00133
00134 ObservedSelState( SelState & cstate_r, const PMSelectable * item_r,
00135 PMManager *& mgr_r, SelectableNotify notifyFnc_r )
00136 : _item( item_r )
00137 , _cstate( cstate_r )
00138 , _mgr( mgr_r )
00139 , _notifyFnc( notifyFnc_r )
00140 {}
00141
00142
00143 typedef bool (SelState::*Manip)( const bool doit );
00144
00145 bool operator()( Manip manip, const bool doit ) {
00146 if ( _mgr && _notifyFnc ) {
00147 SelState old( _cstate );
00148 bool ret = (_cstate.*manip)( doit );
00149 if ( old != _cstate ) {
00150 (_mgr->*_notifyFnc)( _item, old, _cstate );
00151 }
00152 return ret;
00153 }
00154
00155 return (_cstate.*manip)( doit );
00156 }
00157 };
00158
00159 ObservedSelState _observedState;
00160
00161 public:
00162
00163
00164
00165 PMSelectable( const PkgName & name_r, SelectableNotify notify_Fnc_r = 0 );
00166
00167 virtual ~PMSelectable();
00168
00169 public:
00170
00174 const PkgName & name() const { return _name; }
00175
00182 PMObjectPtr installedObj() const { return _installedObj; }
00183
00190 PMObjectPtr candidateObj() const { return _candidateObj; }
00191
00196 unsigned availableObjs() const { return _candidateList.size(); }
00197
00201 PMObjectList::const_iterator av_begin() const { return _candidateList.begin(); }
00202
00206 PMObjectList::const_iterator av_end() const { return _candidateList.end(); }
00207
00211 PMObjectList::const_reverse_iterator av_rbegin() const { return _candidateList.rbegin(); }
00212
00216 PMObjectList::const_reverse_iterator av_rend() const { return _candidateList.rend(); }
00217
00218 public:
00219
00227 PMObjectPtr theObject() const {
00228 if ( _candidateObj )
00229 return _candidateObj;
00230 if ( _installedObj )
00231 return _installedObj;
00232 PMObjectPtr ret = bestCandidate();
00233 if ( ret )
00234 return ret;
00235 if ( availableObjs() )
00236 return *av_begin();
00237 return PMObjectPtr();
00238 }
00239
00244 PMObjectPtr autoCandidate() const;
00245
00249 PMObjectPtr userCandidate() const {
00250 return _userCandidateObj;
00251 }
00252
00256 PMObjectPtr bestCandidate() const {
00257 PMObjectPtr ret = userCandidate();
00258 if ( ret )
00259 return ret;
00260 return autoCandidate();
00261 }
00262
00266 bool setUserCandidate( const PMObjectPtr & obj_r );
00267
00271 bool clrUserCandidate() { return setUserCandidate( PMObjectPtr() ); }
00272
00273 public:
00274
00275
00276
00277
00278
00279
00280 enum UI_Status {
00281 S_Protected,
00282 S_Taboo,
00283
00284 S_Del,
00285 S_Update,
00286 S_Install,
00287
00288 S_AutoDel,
00289 S_AutoUpdate,
00290 S_AutoInstall,
00291
00292 S_KeepInstalled,
00293 S_NoInst,
00294 };
00295
00296 friend std::ostream & operator<<( std::ostream & str, UI_Status obj );
00297
00298 private:
00299
00303 bool intern_set_status( const UI_Status state_r, const bool doit );
00304
00305 public:
00306
00310 bool set_status( const UI_Status state_r );
00311
00315 bool test_set_status( const UI_Status state_r ) { return intern_set_status( state_r, false ); }
00316
00320 UI_Status status() const;
00321
00322 public:
00323
00327 bool providesSources() const;
00328
00332 bool set_source_install( const bool install_r );
00333
00337 bool source_install() const { return _state.is_srcins(); }
00338
00339 public:
00340
00341 enum Fate {
00342 TO_DELETE = -1,
00343 UNMODIFIED = 0,
00344 TO_INSTALL = 1
00345 };
00346
00347 static Fate fate( SelState state_r ) {
00348 if ( state_r.to_modify() ) {
00349 return( state_r.to_delete() ? TO_DELETE : TO_INSTALL );
00350 }
00351 return UNMODIFIED;
00352 }
00353
00354 Fate fate() const { return fate( _state ); }
00355
00359 void setNothingSelected() { _observedState( &SelState::user_unset, true ); }
00360
00367 bool downgrade_condition() const;
00368
00370
00372
00376 bool has_object() const { return _state.has_object(); }
00377
00381 bool has_installed() const { return _state.has_installed(); }
00382
00386 bool has_candidate() const { return _state.has_candidate(); }
00387
00391 bool has_both_objects() const { return _state.has_both_objects(); }
00392
00396 bool has_installed_only() const { return _state.has_installed_only(); }
00397
00401 bool has_candidate_only() const { return _state.has_candidate_only(); }
00402
00403 public:
00404
00408 bool to_modify() const { return _state.to_modify(); }
00409
00413 bool to_delete() const { return _state.to_delete(); }
00414
00418 bool to_install() const { return _state.to_install(); }
00419
00420 public:
00421
00425 bool by_user() const { return _state.by_user(); }
00426
00430 bool by_appl() const { return _state.by_appl(); }
00431
00435 bool by_auto() const { return _state.by_auto(); }
00436
00437 public:
00438
00442 bool is_taboo() const { return _state.is_taboo(); }
00443
00444 public:
00445
00450 bool user_unset() { return _observedState( &SelState::user_unset, true ); }
00451
00456 bool user_set_delete() { return _observedState( &SelState::user_set_delete, true ); }
00457
00462 bool user_set_install() { return _observedState( &SelState::user_set_install, true ); }
00463
00467 bool user_set_taboo() { return _observedState( &SelState::user_set_taboo, true ); }
00468
00472 bool user_clr_taboo() { return _observedState( &SelState::user_clr_taboo, true ); }
00473
00474 public:
00475
00480 bool appl_unset() { return _observedState( &SelState::appl_unset, true ); }
00481
00486 bool appl_set_delete() { return _observedState( &SelState::appl_set_delete, true ); }
00487
00493 bool appl_force_install() { return _observedState( &SelState::appl_set_install, true ); }
00494
00500 bool appl_set_install() { return !downgrade_condition() && appl_force_install(); }
00501
00502 public:
00503
00508 bool auto_unset() { return _observedState( &SelState::auto_unset, true ); }
00509
00514 bool auto_set_delete() { return _observedState( &SelState::auto_set_delete, true ); }
00515
00521 bool auto_force_install() { return _observedState( &SelState::auto_set_install, true ); }
00522
00528 bool auto_set_install() { return !downgrade_condition() && auto_force_install(); }
00529
00530 private:
00531
00539 bool do_set_onSystem( bool (PMSelectable::*fnc_unset)(), bool (PMSelectable::*fnc_install)() ) {
00540 if ( has_installed() ) {
00541 if ( ! to_delete() )
00542 return true;
00543 return (this->*fnc_unset)();
00544 } else {
00545 if ( to_install() )
00546 return true;
00547 return (this->*fnc_install)();
00548 }
00549 }
00550
00558 bool do_set_offSystem( bool (PMSelectable::*fnc_unset)(), bool (PMSelectable::*fnc_delete)() ) {
00559 if ( has_installed() ) {
00560 if ( to_delete() )
00561 return true;
00562 return (this->*fnc_delete)();
00563 } else {
00564 if ( ! to_install() )
00565 return true;
00566 return (this->*fnc_unset)();
00567 }
00568 }
00569
00570 public:
00571
00578 bool is_onSystem() const {
00579 if ( has_installed() )
00580 return( ! to_delete() );
00581 else
00582 return( to_install() );
00583 }
00584
00591 bool is_offSystem() const { return( ! is_onSystem() ); }
00592
00596 bool user_set_onSystem() { return do_set_onSystem( &PMSelectable::user_unset, &PMSelectable::user_set_install ); }
00597
00601 bool user_set_offSystem() { return do_set_offSystem( &PMSelectable::user_unset, &PMSelectable::user_set_delete ); }
00602
00606 bool appl_set_onSystem() { return do_set_onSystem( &PMSelectable::appl_unset, &PMSelectable::appl_set_install ); }
00607
00611 bool appl_set_offSystem() { return do_set_offSystem( &PMSelectable::appl_unset, &PMSelectable::appl_set_delete ); }
00612
00616 bool auto_set_onSystem() { return do_set_onSystem( &PMSelectable::auto_unset, &PMSelectable::auto_set_install ); }
00617
00621 bool auto_set_offSystem() { return do_set_offSystem( &PMSelectable::auto_unset, &PMSelectable::auto_set_delete ); }
00622
00623 public:
00624
00628 virtual std::ostream & dumpOn( std::ostream & str ) const;
00629
00633 std::ostream & dumpStateOn( std::ostream & str ) const;
00634
00635 public:
00636
00640 typedef bool (PMSelectable::*Test_method)() const;
00641
00645 typedef bool (*Test_fnc)( const constPMSelectablePtr & sel_r );
00646
00650 static bool test( const constPMSelectablePtr & sel_r, Test_method fnc_r ) {
00651 if ( sel_r && fnc_r )
00652 return (sel_r.operator->()->*fnc_r)();
00653 return false;
00654 }
00655 };
00656
00658
00659 #endif // PMSelectable_h
00660