From ce32f25ba3d616eba40d5f88781dd8bbcb0759f0 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 13 Jul 2010 17:05:47 +0200 Subject: [PATCH] QmlOutline: Show icons for known types --- .../qmlicons/Qt/16x16/BorderImage.png | Bin 0 -> 416 bytes .../qtcreator/qmlicons/Qt/16x16/Flickable.png | Bin 0 -> 406 bytes .../qtcreator/qmlicons/Qt/16x16/Flipable.png | Bin 0 -> 512 bytes .../qmlicons/Qt/16x16/FocusScope.png | Bin 0 -> 367 bytes .../qtcreator/qmlicons/Qt/16x16/GridView.png | Bin 0 -> 320 bytes share/qtcreator/qmlicons/Qt/16x16/Image.png | Bin 0 -> 579 bytes share/qtcreator/qmlicons/Qt/16x16/Item.png | Bin 0 -> 303 bytes .../qtcreator/qmlicons/Qt/16x16/ListView.png | Bin 0 -> 339 bytes .../qtcreator/qmlicons/Qt/16x16/MouseArea.png | Bin 0 -> 459 bytes .../qtcreator/qmlicons/Qt/16x16/PathView.png | Bin 0 -> 334 bytes .../qtcreator/qmlicons/Qt/16x16/Rectangle.png | Bin 0 -> 236 bytes share/qtcreator/qmlicons/Qt/16x16/State.png | Bin 0 -> 316 bytes share/qtcreator/qmlicons/Qt/16x16/Text.png | Bin 0 -> 224 bytes .../qtcreator/qmlicons/Qt/16x16/TextEdit.png | Bin 0 -> 249 bytes .../qtcreator/qmlicons/Qt/16x16/TextInput.png | Bin 0 -> 327 bytes .../qmlicons/Qt/16x16/Transition.png | Bin 0 -> 247 bytes .../qmlicons/QtWebkit/16x16/WebView.png | Bin 0 -> 544 bytes src/libs/qmljs/qmljsicons.cpp | 58 +++++++++++++ src/libs/qmljs/qmljsicons.h | 9 +- src/plugins/qmljseditor/qmljseditor.cpp | 2 +- src/plugins/qmljseditor/qmljseditorplugin.cpp | 8 ++ src/plugins/qmljseditor/qmljseditorplugin.h | 1 + src/plugins/qmljseditor/qmloutlinemodel.cpp | 77 ++++++++++++++---- src/plugins/qmljseditor/qmloutlinemodel.h | 8 +- 24 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 share/qtcreator/qmlicons/Qt/16x16/BorderImage.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Flickable.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Flipable.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/FocusScope.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/GridView.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Image.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Item.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/ListView.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/MouseArea.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/PathView.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Rectangle.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/State.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Text.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/TextEdit.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/TextInput.png create mode 100644 share/qtcreator/qmlicons/Qt/16x16/Transition.png create mode 100644 share/qtcreator/qmlicons/QtWebkit/16x16/WebView.png diff --git a/share/qtcreator/qmlicons/Qt/16x16/BorderImage.png b/share/qtcreator/qmlicons/Qt/16x16/BorderImage.png new file mode 100644 index 0000000000000000000000000000000000000000..ef21dd9710709b536736c433368d595b2fe298fc GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4+=20xv5*E29Ma29w(7Bet#3xhBt!>lS@xOMx|`z`JZJ~1wMZu-r0%f(~I!WC0w6V^4I zP`r2a_oUo^H~$)c_Mf&$BOvsD^J7uhgI=Mw3J=Of1QzI?-Xwh_RK#^x-1_P9E0vTw zI96G$u4jx{A8wbp`|hK?S|Ood)pOq@JSeaTxNe#`Ym&;zCyNZ*R6IGF8b1F#qtg8Q zFW-T>{p#n7T~ao_UA1b*-MrJvCccN$Hb4AW;d5@m-y_v!ewU{#%Y3nm@3~B&jPP;8 zb2|f#kNJF(Ft(8Ee^X|?NoR3x^qk_!Z+T{IEt5$UOS=EPgJb&X)N8M_bJGOc6t6|~ z7)E5LM{l?$)b?=G!IveoRR3!IO%DqcS^55Ve)#vkhsJ@^Qva`H{Qpqed+Ny&+q^g# PP~dvH`njxgN@xNAf+DXO literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/Flickable.png b/share/qtcreator/qmlicons/Qt/16x16/Flickable.png new file mode 100644 index 0000000000000000000000000000000000000000..963a7afea358303873397bfd01b9088d6b990287 GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`&N| z?e4gptwJSSce68}7WI1RTE7How@Yv$i7n}1gD#C{i{uCaXrm!eAvPGae zI;!IbuY%IKpS#xCf1BKpGR0S-P4M`}Et_>tZ_1hM)M4W5d-+d7kKy^xlT>!bt^Z%L z`Tg(Tf8#=@Zu@F@{DiiFU2vxF@togM9UaqB=O*oASSm3?AnI|1AOiyfgQu&X%Q~lo FCIC4$p%nlC literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/Flipable.png b/share/qtcreator/qmlicons/Qt/16x16/Flipable.png new file mode 100644 index 0000000000000000000000000000000000000000..354f5bd91c30220917b3863200ee6c874c4bd015 GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4f>=!(4800mj#OiF--e>xW zv(&tT7T(NRv`TAdOyA3rUxJf3Iu>!9-gM*r_bs<`^R`R>teNMu@Ia2)Z*vE)&ULR} z?DAWE^-iSP-k44ofy`glX=O&z`&N| z?e4Kyc4`1lAXer~x0!=;vO;h%Tx1KP~>1Y#H$e6(2U>mLCrqi_M z#zdW;x96>&`O|EYM%N?uA5U2Ke7AW1;U04h|KSg*DifdYT(!zd)#`b{ImJxd?Ay}{ zWqK#NOiO*Wt4~|w^rXyLXLLPwcOCf25SHmVi6LQa?DvKD?z8tzbeXm6)$e&Ko-1BU zz5ly%)w0YD*MdY?Kim9|y3zJo{^yB9!EDi)=^SNz(r>QDgl*t`$Mf*)%BI!HE<%Me zr=zqT8rE#pf34A_^75yAOT)KD*{hAk%n{R`=5ptoM=bxkeJ6Xp__bIe{wDd`l56&V S@?l_LVDNPHb6Mw<&;$TEwv$T$ literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/GridView.png b/share/qtcreator/qmlicons/Qt/16x16/GridView.png new file mode 100644 index 0000000000000000000000000000000000000000..011392dc557b73596cde95264b91dff8e2624bfc GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`&N| z?e4(`VQY*qpCeX5!nsW0A(6?#x*XDUr_(r$#bJl&@Rm<#T%* z-?dWRWtmcj$Npk44ofy`glX=O&z`&N| z?e44csU%NNML~2&hsUNN{w?_5$`=~8uuKyv) z%5h-j_1EvNFBR)`o0>VRK3uc)u?2^s0T1*1^XYn4tO$QY|R?JD-_(P!FO7`4yVeWOlyiB+$_qot}1XVaR+ zx{rovO?^~irPxxj^7h+rYd>^k44ofy`glX=O&z`&N| z?e4dwn1Oo%Z zdQTU}5R21GCvN0zb`W3@kKtrw>6qZ8prBBm5XkBqaYD9M^gg@L^1>8u=3{#zUpDim zEu9^H|2vaj{T_(`mLsW=cE<|$WT`hS%bYax~(ot zPa%fA?B5=&S`}7nD!^p@d>eb;q1oy!2WB&W{?k-0E7Q2&DxxlQLi4iBbCw*9;e4NL z?4K)~-lR}b=frX(bJo4HZZH3=9kmp00i_>zopr08W-_ A+yDRo literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/ListView.png b/share/qtcreator/qmlicons/Qt/16x16/ListView.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e62ca068f82f81e9f09e778f63f8387f7d2776 GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4;`pJ6Y}(9vx%*MPJu5 zFfd&9ba4!^IK6hVVPCU>h)a8ei({*cbE8Z1ox)~~={K|V8+W(_JuwN)dpOToL3w}f zHN}i@!9Jr)`p5rQ9`j@PT3bK&`A=_smJ^oh?`vnAHu1gBbfr{w{yFl(xgM8TM+~Zy#G7RCdU{?H0dql~%)Fmc-xtS$r?M2v14fDb(U{tniNL z0|TDh0`sFSWc&5cZvS0-`A~Xx&AkoZ85n=9Rq?8vw_Z{2w9wxPW-P9OF2X61+y1dW pzjIrWD`3{L=PI5ZbBq_rKhIn-oh9U^H3I_!gQu&X%Q~loCIF(5f4Tqw literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/MouseArea.png b/share/qtcreator/qmlicons/Qt/16x16/MouseArea.png new file mode 100644 index 0000000000000000000000000000000000000000..b28576ac8772a6ae778ee1ac543be04c1ab5f665 GIT binary patch literal 459 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`&N| z?e4#y~D0zw=Ge3oCn{Wfh@nrcIk7e}Oy*pwjO%m3J20(%y92pG*in-VF< z!!|9omU-6MG@0Yyf6o;#lIwr|dFS)WUF+%@_AkudD#dWFQpELr=j&YzCcf5l{Z#o@ zU(MQno3Z1u#DQvCr;f)KZHZGXG`c1&%amx_q_bcB^iw0>%f}yId|Befz;OQg_8FFrK)A1H) zIj@}>8D`Rc_+kE%(@!Uk44ofy`glX=O&z`&N| z?e4;`pJ6Y}(9z#j#(tuP3 z28MH=7Ou-U?{G#rI}1$t5hKAR z5?yxY0DDaN|NHgr#tpA_{o_)U`LcxJsKnHus9(i0#}_k%hPviWP32V3_S95;dTr57 z-H$3OGiU8Sm?$BqW#H`cde`TytD0X|1(>T?QHVD|1Nv+yQc1Jg6)rR zrrmZY>IGOfTKivG@z{*s4GGc?_o|&ZBH7Map8cG| ka>BCQ=-7mt>JH-5|NPQhwPsHT0|Nttr>mdKI;Vst0H2k44ofy`glX=O&z`&N| z?e4;`pJ6Y}(9wV0Excqts z28J9@7sn8b({C?r6l7N9VZF#Y$7(;*i~UMmi4MPZF}?YCL*r}rQdw3l!H-X>*(?+k z7^dEJYOE*J?S2@#zWKP6$1kUgQu&X%Q~loCIGgjO=bW9 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/State.png b/share/qtcreator/qmlicons/Qt/16x16/State.png new file mode 100644 index 0000000000000000000000000000000000000000..d400b013aeb020c7a656826ad25c2afd827f9a48 GIT binary patch literal 316 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`$AH z5n0T@z%2~Ij105pNH8!ku$OrHy0YJ5=i!s#>fW8t!N9<9&eO#)MC1I_ppCpO20TaF z7=zk+96S$Nne=#^Ek&z!=i7obip~nz^0Dc z`|jT-q)K`%oD$^qGdJ*$m>d5@j_B*AFFGG>zt^@%!)4R8ZMmmAYyTVYv?tDczASUb z^i)mf%6Y~sUt9I4C@4K-_)yyJz2RoP(#P)oY)XgZC(f{VF3`V``|u_mCk6$JIfpmo zN>4WNZH>tOUb{acDmymx>d)w1>mDaWz2-k`;`==3u>~6!LxbV7i@JLmTwcY#o3&-u RA_fKq22WQ%mvv4FO#nnBd6WPE literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/Text.png b/share/qtcreator/qmlicons/Qt/16x16/Text.png new file mode 100644 index 0000000000000000000000000000000000000000..a49a39c33c6a882f898ead68dc81122f2d0ddf05 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`&N| z?e4+=20xv5*E29Ma29w(7Bet#3xhBt!>l0}tz`&5; z>Ealoaei;$N!|kn9FJ!;z1c6(>>xjNQP+~djMcx6DsJFivFZ$ubO%SdxRR0a4d?9M z1s$InzHkU$XNxnAxjrXH^DNKay%#>aT$-OQ`&ad~aNA4mpul(QKF(whxq9gUqiLwz UAzS%BJ3x-}boFyt=akR{0KR=mQvd(} literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/TextEdit.png b/share/qtcreator/qmlicons/Qt/16x16/TextEdit.png new file mode 100644 index 0000000000000000000000000000000000000000..4f41cd9bc5269d0f4eb348e8a0fc25ff44ffbcc9 GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`&N| z?e4;`4g{~iu2*sO+uRd|kXW z-^nYo6n0CnF)*YlroF4HesOq0@iFdIzoa}vk5^nf-*)`t-wXGGyfV*j_;cv`^5+cG yRn!fSeLH!F({uMr@7l7PR?A)?cR(WsegsscNDj66U7(8A5T-G@yGywo#ELqwB literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/TextInput.png b/share/qtcreator/qmlicons/Qt/16x16/TextInput.png new file mode 100644 index 0000000000000000000000000000000000000000..394ac907cf686515d102e0b366fec7665deb920b GIT binary patch literal 327 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4+=20xv5*E29Ma29w(7Bet#3xhBt!>lJ4_afmobKhgWv=SE%C5+(`*ON` z=BzZ0)1O*}Cmz|P6L9q`!=8tGpT}0dpZV9w(Pe_xBnF01*KKU8_bW}h!4ahK$e-t+ zEZ3w0MMs}Pw$eb zTor1$+5hOU+>^?4mGgWbU(0NHt}N=hQUBqoi1O+QyDmNamiC_`XcmW{zopr08%Y_NdN!< literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmlicons/Qt/16x16/Transition.png b/share/qtcreator/qmlicons/Qt/16x16/Transition.png new file mode 100644 index 0000000000000000000000000000000000000000..86f591ff7bdc287872b1170e1d5c54f3fa639115 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFL7>k44ofy`glX=O&z`$AH z5n0T@z%2~Ij105pNH8!ku$OrHy0YJ5=iyV+sgXD7VPIhB^mK6y(Kx?#(m`GpMGjY1 z-Gk44ofy`glX=O&z`&N| z?e4+=20xv5*E29Ma29w(7Bet#3xhBt!>lEaloaenHggIuc|MB0vf%5GLL(wwo;mCMyyIb-tc1-bcRUu3p@5Oum09-zSDDx%tv zqTy>%{&4TawY%=;o%{LEa!#T}PvOD<2Kx!iG?RPU1?2eHKS;L-{9A1@|NQdHFCTwQ z=<%EsvNlZi_)n3d#)}y$98P=V-k0qbIAqZmdwr`;_Qr@kvOhAlyOL%-`}|X-MZn1= z@Xgn%CWVM;Uu9?bsBtLX|33ZnQk~O@68qxTN3AWhn_n8MFV_9|qlNg6xb>@6eX=?K z`A>qu1eMMpE=3m(*T5r%cb*oVd|R;perc?@t004ertf8w)$NHDyYDhE1d7zYSMUtl zd^1Gk=;u8O92!ff1UY%^zNs4R{Wl s_}<=Tzgr^Nfg{nr+3=acu?O`(m~Wl?>000;vm6w;p00i_>zopr0NX#~_y7O^ literal 0 HcmV?d00001 diff --git a/src/libs/qmljs/qmljsicons.cpp b/src/libs/qmljs/qmljsicons.cpp index 710e619847f..f423c124466 100644 --- a/src/libs/qmljs/qmljsicons.cpp +++ b/src/libs/qmljs/qmljsicons.cpp @@ -28,17 +28,29 @@ **************************************************************************/ #include "qmljsicons.h" +#include +#include +#include +#include using namespace QmlJS; using namespace QmlJS::AST; +enum { + debug = false +}; + namespace QmlJS { +Icons *Icons::m_instance = 0; + class IconsPrivate { public: QIcon elementIcon; QIcon propertyIcon; + QHash,QIcon> iconHash; + QString resourcePath; }; } // namespace QmlJS @@ -52,9 +64,55 @@ Icons::Icons() Icons::~Icons() { + m_instance = 0; delete m_d; } +Icons *Icons::instance() +{ + if (!m_instance) + m_instance = new Icons(); + return m_instance; +} + +void Icons::setIconFilesPath(const QString &iconPath) +{ + if (iconPath == m_d->resourcePath) + return; + + m_d->resourcePath = iconPath; + + if (debug) + qDebug() << "QmlJSIcons -" << "parsing" << iconPath; + QDir topDir(iconPath); + foreach (const QFileInfo &subDirInfo, topDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) { + if (debug) + qDebug() << "QmlJSIcons - parsing" << subDirInfo.absoluteFilePath(); + const QString packageName = subDirInfo.fileName(); + QDir subDir(subDirInfo.absoluteFilePath() + QLatin1String("/16x16")); + foreach (const QFileInfo &iconFile, subDir.entryInfoList(QDir::Files)) { + QIcon icon(iconFile.absoluteFilePath()); + if (icon.isNull()) { + if (debug) + qDebug() << "QmlJSIcons - skipping" << iconFile.absoluteFilePath(); + continue; + } + if (debug) + qDebug() << "QmlJSIcons - adding" << packageName << iconFile.baseName() << "icon to database"; + QPair element(packageName, iconFile.baseName()); + m_d->iconHash.insert(element, icon); + } + } +} + +QIcon Icons::icon(const QString &packageName, const QString typeName) const +{ + QPair element(packageName, typeName); + if (debug) + qDebug() << "QmlJSIcons - icon for" << packageName << typeName << "requested" << m_d->iconHash.contains(element); + return m_d->iconHash.value(element); +} + QIcon Icons::icon(Node *node) const { if (dynamic_cast(node)) { diff --git a/src/libs/qmljs/qmljsicons.h b/src/libs/qmljs/qmljsicons.h index 783e5ac4d6d..47cec83ef16 100644 --- a/src/libs/qmljs/qmljsicons.h +++ b/src/libs/qmljs/qmljsicons.h @@ -41,14 +41,21 @@ class IconsPrivate; class QMLJS_EXPORT Icons { public: - Icons(); ~Icons(); + static Icons *instance(); + + void setIconFilesPath(const QString &iconPath); + + QIcon icon(const QString &packageName, const QString typeName) const; QIcon icon(AST::Node *node) const; QIcon objectDefinitionIcon() const; QIcon scriptBindingIcon() const; +private: + Icons(); + static Icons *m_instance; IconsPrivate *m_d; }; diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index b7144f1f30d..7528acd51b2 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -850,7 +850,7 @@ void QmlJSTextEditor::updateOutlineNow() return; } - m_outlineModel->update(document); + m_outlineModel->update(document, snapshot); updateOutlineIndexNow(); } diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index d55d5b31dcf..944d34ae4ce 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -39,6 +39,7 @@ #include "qmljsoutline.h" #include "qmljspreviewrunner.h" #include "qmljsquickfix.h" +#include "qmljs/qmljsicons.h" #include @@ -186,6 +187,13 @@ void QmlJSEditorPlugin::extensionsInitialized() { } +ExtensionSystem::IPlugin::ShutdownFlag QmlJSEditorPlugin::aboutToShutdown() +{ + delete QmlJS::Icons::instance(); // delete object held by singleton + + return IPlugin::aboutToShutdown(); +} + void QmlJSEditorPlugin::openPreview() { Core::EditorManager *em = Core::EditorManager::instance(); diff --git a/src/plugins/qmljseditor/qmljseditorplugin.h b/src/plugins/qmljseditor/qmljseditorplugin.h index af6e5f9280c..9fa7ba4a97e 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.h +++ b/src/plugins/qmljseditor/qmljseditorplugin.h @@ -77,6 +77,7 @@ public: // IPlugin bool initialize(const QStringList &arguments, QString *errorMessage = 0); void extensionsInitialized(); + ShutdownFlag aboutToShutdown(); static QmlJSEditorPlugin *instance() { return m_instance; } diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp index bad1f2b7b3c..0a56622ba11 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.cpp +++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp @@ -1,7 +1,11 @@ #include "qmloutlinemodel.h" #include +#include +#include +#include #include +#include #include using namespace QmlJS; @@ -11,7 +15,8 @@ enum { debug = false }; -namespace { +namespace QmlJSEditor { +namespace Internal { class QmlOutlineModelSync : protected AST::Visitor { @@ -22,14 +27,23 @@ public: { } - void operator()(Document::Ptr doc) + void operator()(Document::Ptr doc, const Snapshot &snapshot) { m_nodeToIndex.clear(); + // Set up lookup context once to do the element type lookup + // + // We're simplifying here by using the root context everywhere + // (empty node list). However, creating the LookupContext is quite expensive (about 3ms), + // and there is AFAIK no way to introduce new type names in a sub-context. + m_context = LookupContext::create(doc, snapshot, QList()); + if (debug) qDebug() << "QmlOutlineModel ------"; if (doc && doc->ast()) doc->ast()->accept(this); + + m_context.clear(); } private: @@ -64,7 +78,7 @@ private: } - + typedef QPair ElementType; bool visit(AST::UiObjectDefinition *objDef) { if (!validElement(objDef)) { @@ -78,8 +92,14 @@ private: + objDef->lastSourceLocation().length; const QString typeName = asString(objDef->qualifiedTypeNameId); - const QString id = getId(objDef); - QModelIndex index = m_model->enterElement(typeName, id, location); + + if (!m_typeToIcon.contains(typeName)) { + m_typeToIcon.insert(typeName, getIcon(objDef)); + } + const QIcon icon = m_typeToIcon.value(typeName); + QString id = getId(objDef); + + QModelIndex index = m_model->enterElement(typeName, id, icon, location); m_nodeToIndex.insert(objDef, index); return true; } @@ -112,10 +132,33 @@ private: } bool validElement(AST::UiObjectDefinition *objDef) { - // For 'Rectangle { id }', id is parsed as UiObjectDefinition ... Filter this out.ctan + // For 'Rectangle { id }', id is parsed as UiObjectDefinition ... Filter this out. return objDef->qualifiedTypeNameId->name->asString().at(0).isUpper(); } + QIcon getIcon(AST::UiObjectDefinition *objDef) { + const QmlJS::Interpreter::Value *value = m_context->evaluate(objDef->qualifiedTypeNameId); + + if (const Interpreter::ObjectValue *objectValue = value->asObjectValue()) { + do { + QString module; + QString typeName; + if (const Interpreter::QmlObjectValue *qmlObjectValue = + dynamic_cast(objectValue)) { + module = qmlObjectValue->packageName(); + } + typeName = objectValue->className(); + + QIcon icon = m_model->m_icons->icon(module, typeName); + if (! icon.isNull()) + return icon; + + objectValue = objectValue->prototype(m_context->context()); + } while (objectValue); + } + return QIcon(); + } + QString getId(AST::UiObjectDefinition *objDef) { QString id; for (AST::UiObjectMemberList *it = objDef->initializer->members; it; it = it->next) { @@ -137,19 +180,19 @@ private: QmlOutlineModel *m_model; + LookupContext::Ptr m_context; + QHash m_nodeToIndex; + QHash m_typeToIcon; int indent; }; - -} // namespace - -namespace QmlJSEditor { -namespace Internal { - QmlOutlineModel::QmlOutlineModel(QObject *parent) : QStandardItemModel(parent) { + m_icons = Icons::instance(); + const QString resourcePath = Core::ICore::instance()->resourcePath(); + QmlJS::Icons::instance()->setIconFilesPath(resourcePath + "/qmlicons"); } QmlJS::Document::Ptr QmlOutlineModel::document() const @@ -157,7 +200,7 @@ QmlJS::Document::Ptr QmlOutlineModel::document() const return m_document; } -void QmlOutlineModel::update(QmlJS::Document::Ptr doc) +void QmlOutlineModel::update(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot) { m_document = doc; @@ -166,12 +209,12 @@ void QmlOutlineModel::update(QmlJS::Document::Ptr doc) m_currentItem = invisibleRootItem(); QmlOutlineModelSync syncModel(this); - syncModel(doc); + syncModel(doc, snapshot); emit updated(); } -QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id, const AST::SourceLocation &sourceLocation) +QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id, const QIcon &icon, const AST::SourceLocation &sourceLocation) { QStandardItem *item = enterNode(sourceLocation); if (!id.isEmpty()) { @@ -179,8 +222,8 @@ QModelIndex QmlOutlineModel::enterElement(const QString &type, const QString &id } else { item->setText(type); } + item->setIcon(icon); item->setToolTip(type); - item->setIcon(m_icons.objectDefinitionIcon()); return item->index(); } @@ -193,7 +236,7 @@ QModelIndex QmlOutlineModel::enterProperty(const QString &name, const AST::Sourc { QStandardItem *item = enterNode(sourceLocation); item->setText(name); - item->setIcon(m_icons.scriptBindingIcon()); + item->setIcon(m_icons->scriptBindingIcon()); return item->index(); } diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h index f2e914a36c7..dbc3e7f217b 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.h +++ b/src/plugins/qmljseditor/qmloutlinemodel.h @@ -20,9 +20,9 @@ public: QmlOutlineModel(QObject *parent = 0); QmlJS::Document::Ptr document() const; - void update(QmlJS::Document::Ptr doc); + void update(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot); - QModelIndex enterElement(const QString &typeName, const QString &id, const QmlJS::AST::SourceLocation &location); + QModelIndex enterElement(const QString &typeName, const QString &id, const QIcon &icon, const QmlJS::AST::SourceLocation &location); void leaveElement(); QModelIndex enterProperty(const QString &name, const QmlJS::AST::SourceLocation &location); @@ -40,7 +40,9 @@ private: QmlJS::Document::Ptr m_document; QList m_treePos; QStandardItem *m_currentItem; - QmlJS::Icons m_icons; + QmlJS::Icons *m_icons; + + friend class QmlOutlineModelSync; }; } // namespace Internal