From 27642f332c481129b7b2346d9efcec1804e70aeb Mon Sep 17 00:00:00 2001 From: auria Date: Sun, 30 Jun 2013 00:29:43 +0000 Subject: [PATCH] Apply patch by xenux to filter addons, thanks a lot\! git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@13035 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/gui/addons_screen.stkgui | 17 ++++-- data/gui/search.png | Bin 0 -> 6099 bytes src/addons/addon.cpp | 39 ++++++++++++++ src/addons/addon.hpp | 3 ++ src/states_screens/addons_screen.cpp | 78 ++++++++++++++++++++++++++- src/states_screens/addons_screen.hpp | 10 ++++ src/utils/time.hpp | 29 ++++++++++ 7 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 data/gui/search.png diff --git a/data/gui/addons_screen.stkgui b/data/gui/addons_screen.stkgui index 412d6ae23..4619db7ee 100644 --- a/data/gui/addons_screen.stkgui +++ b/data/gui/addons_screen.stkgui @@ -5,11 +5,22 @@
-
- + +
+ + +
+
+ + o`= zKe##B!Oy4u*QUS+lxS$?zzJTFoIX_WH&?K!6A=LTNe4G%3M(E4c8ZXU9ZB|hEGg8J zfB`~7LlyjS0Yq=lV2lEu;Cq*;EeZ}gaxln%O!C7M0B{^J+%weQ6Bppg(|qAJ06-)U z{zhYn-UR<(l0O~?Anh@p1aChi!rvQ@LtqK`AcVFj!jFK#>LC3{q+m@&MUp4Z7q5UN zU@$%yVgLyre6XCN!$Ge*_^N{*cN+r!D#n|H)J6R5NBrkELR-;O7s2a_)Al0h9^Bwp zdw-la1`&cG5W)2kN($-<8cP4)tOHqy2vAFe4cRNu-y4C(2YLGAH2;^PohM+fkuf+@ z;B|KcVgSa+-Ik0Y9%xIHbifdTi0*i-`$Zx~LFN4akoUZS?O&OZ`DVhPH6;$rWkkSu z9?V8K_y=JCWhIo-86}l7%Bl{ibDAn=HI>zy<+omdgRTDCKV*V82KbNZ@WB|Icc6c; zCxP_WXg(N{r+=WL%2{RgbN_AEGsNpe5+>*j@vj@scwIm9e|rs~8QclJ+3c?v_~7dV ze_uZm@c$SE@t>u<|4JEx@x})QftvnZ4m2GGN5l{nga4Y*=dTqNojUg30Dz#h8QQ=h z?B3Gdm^9Z9x8_>rnlCSZc=nW8QGr`u7RN=CypJ5a=aWz!FZtE;Rgh^2S8Q^7TKjnw zzr8#+V@^-uaZ z{9NC@wyd#jLSAo&`pV=pVZL*wCv|=_g)(&tHP;J>gH1Ql(0#qstvan0|J0^}H|xvO z_|cIO)$QhGy?=Woxq;}}kLe>r8V-C2S;C;>nn;0M+3y_o=DAwG~-Tr)Sw zWOB#)bWBX0^zjYBZ-r2g{k`1~WY!C7^j;=4WMp*IMQtifQaPW8KN+e$7(c5{eZbkg zTw+&>xZUeXA_)j7xB@D3fc9WtOap$p`SR#MSY${flb$VO?G+g*21H9C`SgAd87)`R zV)qp{X%HSBp5N3S_r{8d)u88}lA4=!0sT@3L$EctG8EsLp-rXuO{KHJ22k?zMR@r5 zys=mYuz_oEjh=aHBF-Cwc^1vJNdv?*N%N^d^h(2ERK@397hEjHsplKP(b<_r#R#~U zf6BwBhLY$-O*Et$I+aL!O4`pNvI)U%CcG6vl@N%Hxx{^|l8TDM$hhii)T@mzsVhhP#%5+ z3IT~9U8Il6i4_4i=;iIQUmS(cTb-odtEu!RzZS;*?4NPR;f;uzhkI*=hK4A2?uh!- zI*DlzpcgJ&5X#%^-Tt$rwN}ciPMRNTsSetHT^X~x;CJ_H2=j?9BYzlDvEOTx;YP9&wxq^H{WJ4PKdPo22@!Ohqi$J3BjP_G4{9 z&nY{#&Q6Q7aa)A?&T{ly<`wBZH zmH3EvZLY*rOR?bIo4_Z;w*}V#AU!?Z^znQ3h(C)TxVgD$_q9S#xCa2Y-MGO7_~`F6 z(%%@eWJt4X`|<^OUYdJ@Ii&HMgvB;CPVDWinQ=F_9m2{h)C#W%5t|C?*^Y?PGz%CHs=b z{jgZLq&!b6#RH*)e#qq`;K8Yczyd6AG$UB>!9V>?Zj~32s)P6P3}H~&qp5y@ft_F; zLT0S_#C1P5GXdb^bMnH-2ehw(_?LO>nz6AdrOz)yf){eXGxIP`$eEu$GJVJ-wmY#@ z-tD6J|fhU<1PC&j_`3LFh&(5AWK)=B?Y2l?` zKmaSn<*=CgP!$fK&R=kIa|0*{&P=!8D2>bKAL*_Y+o5^ut==e&31d6TM8rh0dX!8U z!JRXi#)ep~{F7d$QgN_8IJY4LNij4KWPFXp95sYMim7FWeord%@7z(e52=2c#!jKr zRmbQ-U0&6D^(-r9g2e#~3k#lUu_*SEY&Kcs!-W9F;p@3Z4~v|H5$upok2oMD&om)V z7%)O7^l-+r^~rZ4+hI?wvRMw-Cl3q=)F3|~kZ2DIr$svNIiflIrqxjg7b6yi@E9H3 zh!VTHx~A5kL*HL2q@iH&J|QEiS9#KQ{Gox9!jeAEsBA1pB^=8*S=i$dDNlp_FjQ(4 zr(=Q$6boU6!P~a8yZBho2(opeDOaU1EO4ikoQ1Jln_hW7SYdB{G_`wHzkZ_b5AbJs zTHIQSUu2YAOeR}7pGsPB)nWl$43hO#;?20?&3N(*I&IpKFbQRZCyOJR2c5^(=lCn_ zXS>Go-S+M5O|z3##>qAxZki?tKn_8BlgIb$P!=qdk#Io(Ud{*BtMOCFV7JivC$_(N zz3AnTBC+6y`SqDf9w=&lk1~)aQfBI?pQNAEW?`5Vi|J^45}ueKv0b^h_{ARymrz0( zP;bHH*c=UQkUrzNf=73+Znb>LDwu;Te1r6f!Qgo!^dK;JhffAVZBgt%7vd0)(UB}v zJ5OqwQmwHMwbjrkVJs6_qMyXYE-!DG1dQ--)uSuZTq9+K&=M$(hfu>ZYLV&FB-TK< z#{*L>a`IInV;}Mr74RLWIW zR@p;X-Z#ShVkMhWu55ohJA#!)A`4gLu-I=j7P@Ii$%*?R3Bm||B&R$?9wH)(GVkF` zh&PQ`lk@#H2vMm__`c{2*>Dtgy@DIqYUZN}o03y+byYCX z{14Bf0w5x`LzmW^T@Jya&dGj8oO2iUhF!c{x*ZwIe|EGetJ5H&DzgnQflrT>btw#-y zj>c1~niS(7-%xxQ5jRA3>t3(VVEA6>;`2>yrbNbVp!v&ORZ1zX&H9Pv)zWm9^07-W zZXjFMlL~u!QjR4VfIXd9=9uUeeDleDFY-1L`Jy7#t~8;vR4&0&eeeEqwrhrjs4QssvLPh=ND0+Vdo7w6cH;FOct z>sj4@o~hqU&aR!q;>^`^C!&mwfH>Cfkf-pM#qnCsj+J?5k^N-gMAUCv@z$H&-QBhd zx3jDsXQg$oY(FP?TvZ*tA`d0QkP^}oFnBgH)8>OZr(9Q{95OX$3`s>@6Em!+fgPcq zw8@QglzKqbFLQiblR=B5MdKt|z6CUDmicHWfdvP_sidqNmnx*l-WM6>1_1z-{mtQF zfk%%X73CPZxgC#QXJARH;b#fhFMmvrJ>MG4Vlg#9!%tr@eX1v$%0-tTAig@MxWWnJ znI#Amb&RD3>I3mIFs;sfXZy8TFXVGY1uxeQGrixGW(T5b@CutvSA#*@j&Sgu*zx!T zS)6>nd=b9+w$%P{=HQ&IyZg-qq3(`QcMhsqT83q0e%hGS1E40Mho5RJrCMFXMum4s zu$m-a6XCz%C6wYSO+Zi~RD)#8S6_G;x@%LLT0swfONQd@u6#5G#Rs?TsjykzudADK zll1*vXVDlZ06-x5d~2PE-}^)yP6^i4)fF{Nbu>3_Rpp&lyB{61!?X#oMjVBzW{qWH zW+5C6{MWmBI-&T|ukNcWm$%Elhx7IK_j7i@ z<^~J9L2Y13pASH{c>wQ>5R>}=;p<&5SeI!GU1of^?9Pj2^!4#Dq*piiro|!g<{+ln z)BE{8Sp=RyIRrsNGtfl_4>1~jTqrqd{!F%$s$7BW_qw{gw&%xR>rtJa?AJD`l}=?i z*U{;Qa*1F}ifM)LNJ>h|-ZHlpPKr5+8APuS^=M z2V0xxChs|eX9QzkQgRu0ss{!}O3Vh`Y&!37W%0kGRKcoy{>`OiBD+!?ow{lYHHf(I zWv_}?OB3{m+F_RquU1szsE)abAgL*n@-~3Ytc|*N&&(h|xMrPePSZ+CO2UpD2LLhc zu&Q)w^tw{9x2tZ>*2D&>M*3F>(P+1^^kE|! zEsEv=+AR_Z4LGc7OR0@)6y4^Jn(7D$^IX)P9=|J^x$+cOSQ)h2I3NgLP6qF z^%Nfx5`yW!c|^v_BP8S~$P02Y#kI9Zy1d|ztqU3R^L~e0-QwfpV;VtJH}k7oyyc1< z`5~Q7_wCL&K33()3er}wZUfyylWIpa&CURZVm#t@?7876pV)Kz+*R#k`8n|xI29TVU-7 zTkThq1Y)$+)iR54)T)jJu7ES``UIL0e z8O?&O`^g15?*9GzRYAwzzke@$;zZKORs@kqjHz1`T;T99J}j<#&uQw}_Iot)GidP# zptC{tfqUm!b1-0e39v!$dydhxYPq4rujK5`ah>kZx@ zl|2CH2LT3cJ2fU~Eh})y4_ARrRZ&q1+x&JLEXMBdoMXNv3SH?b*P;ks-}%+um}BS8 zv4R2Ay1Y;q?d^5uVK=+M@NDaQ;&2LVAT0w4y`gZ@djpuZkn!7WYwcg1KLeu&b=H6T zm0Od@y#Btb*A5 zZV2;ZGLwk|-QL&V-?pkP#h-jJZ!a_ zWQgk>hKmS;`97bW^idGp$Nn%sZCk=O2em>Lt0E#IvR?Zrsi@S7O3(h<=x+Ckh|mh0 zWNd7xgA+4kQwmOqiS2a6JXucxXM!}h!BTE*cQEq1NcPlgZ2g^$}TGS~_s2!flsC zSdxUZi_6=osf;k~!=vPDi(@G5-QVwrsB?)d8alva~M+b4y!Knol1FQ(c4L^M?G% z4cumpz_=0{DAeN{C0~AK3g&=#gl-Bltl$P%2B|&W853?|EB{ z`OJ5@SwkO>S9BfS9jnd7w5>;dC1}9jZkQ~)RRe%WSePRpFYl+pzMJ4eXa<7;Gltuh z3W#;b+8z28CYCXKPz7SCk$L7ct7wOAK{c)`R$JTKE$lNbQGaR+$;*w)x)0y`!{BJ> zK`h%_>#%wE>3}t3f1zY~cLV?^O%dzh@!bBGmpFG&4Dc*xWk73r1`JGN3&qulg7xjbSBX?n= current_version); } + +// ---------------------------------------------------------------------------- +/** + * \brief Filter the add-on with a list of words. + * \param words A list of words separated by ' '. + * \return true if the add-on contains one of the words, otherwise false. + */ +bool Addon::filterByWords(const core::stringw words) const +{ + if (words == NULL || words.empty()) + return true; + + std::vector list = StringUtils::split(words, ' ', false); + + for (unsigned int i = 0; i < list.size(); i++) + { + list[i].make_lower(); + + core::stringw name = core::stringw(m_name).make_lower(); + if (name.find(list[i].c_str()) != -1) + { + return true; + } + + core::stringw designer = core::stringw(m_designer).make_lower(); + if (designer.find(list[i].c_str()) != -1) + { + return true; + } + + core::stringw description = core::stringw(m_description).make_lower(); + if (description.find(list[i].c_str()) != -1) + { + return true; + } + } + + return false; +} // filterByWords diff --git a/src/addons/addon.hpp b/src/addons/addon.hpp index 13443ca1e..600ee0dbc 100644 --- a/src/addons/addon.hpp +++ b/src/addons/addon.hpp @@ -266,6 +266,9 @@ public: return file_manager->getAddonsFile(getTypeDirectory()+m_dir_name); } // getDataDir // ------------------------------------------------------------------------ + bool filterByWords(const core::stringw words) const; + // ------------------------------------------------------------------------ + /** Compares two addons according to the sort order currently defined. * \param a The addon to compare this addon to. */ diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index 5122c109f..19f41d138 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -40,6 +40,18 @@ DEFINE_SCREEN_SINGLETON( AddonsScreen ); AddonsScreen::AddonsScreen() : Screen("addons_screen.stkgui") { m_selected_index = -1; + + // Add date filters. + m_date_filters.push_back((DateFilter) {_("All") , 0, 0, 0}); + m_date_filters.push_back((DateFilter) {_("1 week") , 0, 0, 7}); + m_date_filters.push_back((DateFilter) {_("2 weeks") , 0, 0, 12}); + m_date_filters.push_back((DateFilter) {_("1 month") , 0, 1, 0}); + m_date_filters.push_back((DateFilter) {_("3 months") , 0, 3, 0}); + m_date_filters.push_back((DateFilter) {_("6 months") , 0, 6, 0}); + m_date_filters.push_back((DateFilter) {_("9 months") , 0, 9, 0}); + m_date_filters.push_back((DateFilter) {_("1 year") , 1, 0, 0}); + m_date_filters.push_back((DateFilter) {_("2 years") , 2, 0, 0}); + } // AddonsScreen // ---------------------------------------------------------------------------- @@ -70,6 +82,7 @@ void AddonsScreen::loadedFromFile() GUIEngine::ListWidget* w_list = getWidget("list_addons"); w_list->setColumnListener(this); + } // loadedFromFile @@ -83,8 +96,32 @@ void AddonsScreen::beforeAddingWidget() w_list->clearColumns(); w_list->addColumn( _("Add-on name"), 2 ); w_list->addColumn( _("Updated date"), 1 ); -} + + GUIEngine::SpinnerWidget* w_filter_date = + getWidget("filter_date"); + w_filter_date->m_properties[GUIEngine::PROP_MIN_VALUE] = "0"; + w_filter_date->m_properties[GUIEngine::PROP_MAX_VALUE] = + StringUtils::toString(m_date_filters.size() - 1); + + for (int n = 0; n < m_date_filters.size(); n++) + { + w_filter_date->addLabel(m_date_filters[n].label); + } + w_filter_date->setValue(0); + + GUIEngine::SpinnerWidget* w_filter_rating = + getWidget("filter_rating"); + w_filter_rating->m_properties[GUIEngine::PROP_MIN_VALUE] = "0"; + w_filter_rating->m_properties[GUIEngine::PROP_MAX_VALUE] = "4"; + + for (int n = 0; n < 5; n++) + { + w_filter_rating->addLabel(StringUtils::toWString(1.0 + n / 2.0)); + } + + w_filter_rating->setValue(0); +} // ---------------------------------------------------------------------------- void AddonsScreen::init() @@ -147,6 +184,27 @@ void AddonsScreen::tearDown() */ void AddonsScreen::loadList() { + + // Get the filter by words. + GUIEngine::TextBoxWidget* w_filter_name = + getWidget("filter_name"); + core::stringw words = w_filter_name->getText(); + + // Get the filter by date. + GUIEngine::SpinnerWidget* w_filter_date = + getWidget("filter_date"); + int date_index = w_filter_date->getValue(); + Time::TimeType date = Time::getTimeSinceEpoch(); + date = Time::addInterval(date, + -m_date_filters[date_index].year, + -m_date_filters[date_index].month, + -m_date_filters[date_index].day); + + // Get the filter by rating. + GUIEngine::SpinnerWidget* w_filter_rating = + getWidget("filter_rating"); + float rating = 1.0 + w_filter_rating->getValue() / 2.0; + // First create a list of sorted entries PtrVector sorted_list; for(unsigned int i=0; igetNumAddons(); i++) @@ -163,6 +221,19 @@ void AddonsScreen::loadList() if (!addon.isInstalled() && (addons_manager->wasError() || UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED )) continue; + + // Filter by rating. + if (addon.getRating() < rating) + continue; + + // Filter by date. + if (date_index != 0 && Time::compareTime(date, addon.getDate()) > 0) + continue; + + // Filter by name, designer and description. + if (!addon.filterByWords(words)) + continue; + sorted_list.push_back(&addon); } sorted_list.insertionSort(/*start=*/0, m_sort_desc); @@ -364,6 +435,11 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget, loadList(); } } + else if (name == "filter_search") + { + loadList(); + } + } // eventCallback // ---------------------------------------------------------------------------- diff --git a/src/states_screens/addons_screen.hpp b/src/states_screens/addons_screen.hpp index 8b2e370a3..d78a2cac8 100644 --- a/src/states_screens/addons_screen.hpp +++ b/src/states_screens/addons_screen.hpp @@ -28,6 +28,13 @@ namespace irr { namespace gui { class STKModifiedSpriteBank; } } namespace GUIEngine { class Widget; } +struct DateFilter { + core::stringw label; + int year; + int month; + int day; +}; + /** * \brief Addons screen * \ingroup states_screens @@ -70,6 +77,9 @@ private: /** \brief To check (and set) if sort order is descending **/ bool m_sort_desc; + /** List of date filters **/ + std::vector m_date_filters; + public: /** Load the addons into the main list.*/ diff --git a/src/utils/time.hpp b/src/utils/time.hpp index df8ceacec..72e1bff44 100644 --- a/src/utils/time.hpp +++ b/src/utils/time.hpp @@ -86,6 +86,35 @@ public: { return irr_driver->getDevice()->getTimer()->getRealTime()/1000.0; }; // getTimeSinceEpoch + + // ------------------------------------------------------------------------ + /** + * \brief Compare two different times. + * \return A signed integral indicating the relation between the time. + */ + static int compareTime(TimeType time1, TimeType time2) + { + double diff = difftime(time1, time2); + + if (diff > 0) + return 1; + else if (diff < 0) + return -1; + else + return 0; + }; // compareTime + + // ------------------------------------------------------------------------ + /** + * \brief Add a interval to a time. + */ + static TimeType addInterval(TimeType time, int year, int month, int day) { + struct tm t = *gmtime(&time); + t.tm_year += year; + t.tm_mon += month; + t.tm_mday += day; + return mktime(&t); + } class ScopeProfiler {