From 96ede10340199aa1c3b56d856b98be043d8aa72e Mon Sep 17 00:00:00 2001 From: Michael Salgado Date: Tue, 11 Aug 2015 01:04:03 -0500 Subject: [PATCH] * Add functionality to Create Map buttons. * Fix #31 Style Categorized: The generation of CartoCSS fails if there is data with special characters. * Remove unnecessary files in the plugin package. --- CHANGELOG.md | 10 +- Makefile | 3 + dialogs/CreateViz.py | 53 +++++- i18n/en.ts | 24 +++ i18n/es.ts | 24 +++ images/icons/add.png | Bin 987 -> 1189 bytes images/icons/sql.png | Bin 998 -> 1204 bytes images/icons/upload.png | Bin 1154 -> 1361 bytes layers/CartoDBLayer.py | 8 +- metadata.txt | 9 +- test/data/cartocss.less | 350 ++++++++++++++++++++++++++++++++++++++++ ui/CreateViz.ui | 64 +++++--- widgets/ListWidgets.py | 27 ++-- 13 files changed, 521 insertions(+), 51 deletions(-) create mode 100644 test/data/cartocss.less diff --git a/CHANGELOG.md b/CHANGELOG.md index f41ad42..5b6b10b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,17 @@ - -### 0.1.10 (2015-07-31) + +### 0.2.0 (2015-08-10) + +#### Enhancements + +* Add functionality to Create Map buttons. #### Fixes * Fix #25 Error creating map from CartoDB. * Fix #5 Filter data by attribute or extent. * Fix problems with SQL layers in maps. +* Fix #31 Style Categorized: The generation of CartoCSS fails if there is data with special characters. +* Remove unnecessary files in the plugin package. ### 0.1.9 (2015-07-22) diff --git a/Makefile b/Makefile index c9c9071..842cf95 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,9 @@ install: transcompile compile mkdir -p $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) cp -r ./* $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME) rm -R $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/scripts + rm -R $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/test + rm -R $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/qgis_cartodb.egg-info + rm -R $(HOME)/$(QGISDIR)/python/plugins/$(PLUGINNAME)/_site @echo " " uninstall: diff --git a/dialogs/CreateViz.py b/dialogs/CreateViz.py index 1e83c18..d720a86 100644 --- a/dialogs/CreateViz.py +++ b/dialogs/CreateViz.py @@ -43,7 +43,6 @@ class CartoDBPluginCreateViz(CartoDBPluginUserDialog): def __init__(self, toolbar, parent=None): CartoDBPluginUserDialog.__init__(self, toolbar, parent) - self.toolbar = toolbar self.ui = Ui_CreateViz() self.ui.setupUi(self) @@ -77,6 +76,10 @@ def __init__(self, toolbar, parent=None): self.ui.cancelBT.clicked.connect(self.reject) self.ui.saveBT.clicked.connect(self.createViz) self.ui.cartoCssBT.clicked.connect(self.createCartoCss) + self.ui.addAllBT.clicked.connect(self.addAllItems) + self.ui.addBT.clicked.connect(self.addItems) + self.ui.removeAllBT.clicked.connect(self.removeAllItems) + self.ui.removeBT.clicked.connect(self.removeItems) # TODO Implement functionality self.ui.sqlBT.hide() @@ -87,12 +90,52 @@ def __init__(self, toolbar, parent=None): layers = QgsMapLayerRegistry.instance().mapLayers() self.ui.availableList.clear() + cartoDBLayers = 0 for id, ly in layers.iteritems(): if ly.type() == QgsMapLayer.VectorLayer and isinstance(ly, CartoDBLayer): - item = QListWidgetItem(self.ui.availableList) - widget = CartoDBLayerListItem(ly.name(), ly, self.getSize(ly), ly.dataProvider().featureCount()) - item.setSizeHint(widget.sizeHint()) - self.ui.availableList.setItemWidget(item, widget) + cartoDBLayers = cartoDBLayers + 1 + if ly.user == self.currentUser: + item = QListWidgetItem(self.ui.availableList) + widget = CartoDBLayerListItem(ly.name(), ly, self.getSize(ly), ly.dataProvider().featureCount()) + item.setSizeHint(widget.sizeHint()) + self.ui.availableList.setItemWidget(item, widget) + + if cartoDBLayers > 0 and len(self.ui.availableList) == 0: + self.ui.bar.clearWidgets() + self.ui.bar.pushMessage(QApplication.translate('CartoDBPlugin', 'Warning') + '!!', + QApplication.translate('CartoDBPlugin', + 'At least one CartoDB layer should belong or be visible to {}').format(self.currentUser), + level=QgsMessageBar.WARNING) + + def copyItem(self, source, dest, item): + itemWidget = source.itemWidget(item) + newItemWidget = CartoDBLayerListItem(itemWidget.tableName, itemWidget.layer, itemWidget.size, itemWidget.rows) + newItem = source.takeItem(source.row(item)) + + dest.addItem(newItem) + dest.setItemWidget(newItem, newItemWidget) + dest.setItemSelected(newItem, True) + + def addAllItems(self): + self.ui.availableList.selectAll() + self.addItems() + + def addItems(self): + if len(self.ui.availableList.selectedItems()) > 0: + for item in self.ui.availableList.selectedItems(): + self.copyItem(self.ui.availableList, self.ui.mapList, item) + self.ui.mapList.setFocus() + + def removeAllItems(self): + self.ui.mapList.selectAll() + self.removeItems() + + def removeItems(self): + if len(self.ui.mapList.selectedItems()) > 0: + for item in self.ui.mapList.selectedItems(): + self.copyItem(self.ui.mapList, self.ui.availableList, item) + self.ui.availableList.setFocus() + self.validateButtons() def getSize(self, layer): filePath = layer.dataProvider().dataSourceUri() diff --git a/i18n/en.ts b/i18n/en.ts index 176c96e..bd0331d 100644 --- a/i18n/en.ts +++ b/i18n/en.ts @@ -48,6 +48,10 @@ Uploading {} Uploading {} + + Upload Complete + Upload Complete + Using {} of {} Using {} of {} @@ -100,6 +104,10 @@ All layers are SQL layers All layers are SQL layers + + At least one CartoDB layer should belong or be visible to {} + At least one CartoDB layer should belong or be visible to {} + Copy Link Copy Link @@ -256,6 +264,22 @@ Create Create + + Add + Add + + + Remove + Remove + + + Add all + Add all + + + Remove all + Remove all + NewSQL diff --git a/i18n/es.ts b/i18n/es.ts index 237a930..de10880 100644 --- a/i18n/es.ts +++ b/i18n/es.ts @@ -48,6 +48,10 @@ Uploading {} Subiendo {} + + Upload Complete + Capas Cargadas + Using {} of {} Usando {} de {} @@ -100,6 +104,10 @@ All layers are SQL layers Todas las capas son capas SQL + + At least one CartoDB layer should belong or be visible to {} + Al menos una capa de CartoDB debe pertenecer o ser visible a {} + Copy Link Copiar Enlace @@ -256,6 +264,22 @@ Create Crear + + Add + Agregar + + + Remove + Remover + + + Add all + Agregar todas + + + Remove all + Remover todas + NewSQL diff --git a/images/icons/add.png b/images/icons/add.png index 2c1d66f672b235d4997e8db56167c08f09dad681..a999df815376715352d9b45456154b5091c296a4 100644 GIT binary patch delta 1122 zcmV-o1fBca2c-#+Qhx{w1S|!HpZ{k700c5gL_t(o!?l-PXdG1($A5QbcGe`@M7l9e zlcxEgC6<6u6Pkz?6cj@q)Y1kQOOa|H3POcywfNwJptOn~1bneYG5FAmp_CRBq`pKk zs3}QHh&HyR4Q>(xiJNRTyEAj|^wB+qA3V4HmS)1T{-w`NN%v@kIiVBboD z*Y1t;+_^5w@6X3t;NJ7S_jtLnk|%3RGb4~qo!=atq`Cbnc|MctBN3Xm7ole@uq~68 zb3b#eshZCYHe?inb=UdXUvHD=GXbzogPzf;Meg%k27m3p{7o$GX5@iXogb(xTU0{# zCSvpqN0!AVy5!(=3GTBD2F9jnsMwkrff-lQak!a<3@-HC<&|&$SQKM`-Ngaop5#8u zT=8JXQ`8o3Szi?_Z8B2nw3&J0={>yh#BSUr`|~V=P<;hbYo4lkfIyya^UCmp=O5-! z{SKr~l7A@lTO5CE7l$9+$#lY_<51J)_kpu7HLS8y30%23N`L2jSF-k$Z5jB|bgWegn1*03vX&vR zY%^D5naqel+ao(U*L|D6{+&XsaiY?ih$~b3d`2`{VBZPMn=m(t3AXreZ8Oj8KhpR1 z#jix+sZI?rmGJOBI+&bbvOr`yLGay66xbF%BN}~nSGTV+SmT#c;VDVnO`xc*IFCa(&;s8rAuTzC5bsRBs_=7nJ54W&moeC z;z|#{X(P3oPeQ+CaPm^`iqq>_n2x*H)_=T1<8Fd?T8>d2tN=ix2{p75YG?)E_3z%N zFMM;JfNdIS=l1nrzRm?oD}LzjqO_=lgy#@yXr+I6kQ?Dagb)l(jG$D~10%D)OF7K~ zr4`+GuOp=-l86#&XyrzDkZ*p!jHe`0$y5j$XaChiuA0mi|E+DVDt~P*;ausZ@>^t1 zxvL~f>zpZFg!(i4k33jh^(7*ijIQTV6)a1Pvj$3Jhg$+qcsg07~) z5Yh%Ase%<-p&qLDCXX zV=Nk6BM716lJ5L@zvp3RWxDQWXOrC@3^VWd{`|i0z2Eoy-hU`|Fw60ZzzQ%!|7;UD z;k))90J$!WpXzgPfC=D*W}zE^9D^~nn*g6D?e}$fhJDvoo$7##?FP;F06=`#HbBrJ zUtYBw?-}23fiD5m4NSgQo+mTE7x*@D%>qBRH2VVhz<2G%EL+eM z&yyLw)Z(6N)ATvZ@y5DtK^v+`syq!GYqt;?@g4=1djarxLbc{{KM%aurr$3a0sPb} z3r1SXL+x_FckMTTciM~>0G}k^KlrY_)pr{DuH6K27Js;$s;U8R10N>kC$s3mu5=&; zq6~bOxE}@X1YQRo@Ll`YEP9aNtq?Uq0A=73ueDha=e`cO?T3cUI07-{NC@INw+PC2XrISSy$jA;4E+t zU@}Z*e}A(uoU7Fij9f3OTe>Mgaj>v{Xz2XH;>s&m-tPt=_FenIjHl!{@K-bV>ARPQ zr%N+vEySX!M*(64F+wDh=eEN-`!7^Z=Q7YNs}-9c2S%K^$_VG=Ig!*f?5iV$<*&V{-XU$+4Hj0*FPk z9o{5}L;Rby#z_^2+z4t!I;Jo*f;NJ(950EHU zsaxO6m)~Ti`t$!-@M6CNiY`jT6KnmE-fQ{<+4r>KaNZHnuhq5%S5u+C;yz zK!1#|{M%Ku*4zkcRF2Pct-8j?-+x9d8Z8=a8URit|7xmVB6F~?ekhX3bIpW{bVJXS zQvU^yL?g!ZE$A(F?EJ#w+#QE6p&H2;#W9CVcd@ax$v?q1Q34{=QB@5{YB_nK@@cU! tS~kYyv=NLkhzQyUVhm!Ws*NuH3j~F6X%NWN>#hI*002ovPDHLkV1gP4y6^x1 diff --git a/images/icons/sql.png b/images/icons/sql.png index 8b2c422e3a1cc22143bb96f1aa8da689543fb939..fc5b085e8dca645189c39eea223ba7250af933f2 100644 GIT binary patch delta 1137 zcmV-%1djXW2eb*0Qhx{w1THOs95o*R00covL_t(o!_Aj(XjNq#$3M@xXXom6-OQC+ zlj$}z2ZA#11mBoqS+R(mZnzgo_@^*@A(4{wq978IFyCZ>NTw8MG-@^S4+O>5T9&YB z5;~SnabEv5?{>G{bI$Xp7k9gxy0&}Q75lw7aL#$2^ZTCP^MCz*pWh=GCvtbzhk$mV zjLby@sO)`z?NtD4g2C%DoE)GK*gSk=PcS$MP-?@VuO^)}Xj?deD)r}^`s8}}Eq+Q3( z^3$c;JU_pXZGS7vxqK_e8{f7ueM%O4*DU5rbdZflPO-0gF^gx<7#~2oI)A6}3?DXk zu(`5?;1C}w_MD`mXgbZ8ZWB553-7(Kkk(7L>5Y3SEkRm3Z|lCp%xs6fHDR_apU?My zT;*?9vacr0rX?kuxDde>sT0*6t@E`DiWoija?b##uYX1FTAOW8&STa7CZ_MK=h!RD z`158T0w|r4O(@$z8t93|(+4odN-B#JBs+0FLQCfjiu0zD zGc_yW8Gitn)GCl_y!1sY&7C*F5`46}g1LoxyjWhqnnNv2acmCNgcFu+49oZZ2>mYR zz{{Bf@WX2>Xpi)=s2~?7n3(>}tIO%Q-pj{L9jyDTg_B!X@ayYOV+n!O8Loii*en@C z+w%%?*;^B4$5Z7LJ(BbAoG_i_{|_rpbzt06+<%M?BDGF`ClrGIxc}b(G+ww){kx5m z{!_=c$Qoly9v48s5=j-?mcVubnX0@>2|#VdY!0;k#rYe3Oyus`7^1#Pj?1!Qu^i`O zNZe&a0uW3Kb`}J7S8r&4^Xr2mcW1o;=yN6VgBq;BzsFX%(McjAM#-NSH*NOozPS>4lM>D2^0Z%4diX7)+Xik1v(DQxb(xW#XWBaO2 zESxo;xbpF&4+28L?Aiw+LxDl5#Ggv7aHU6Seldl4Gf_$*P2#yR#CrnF1HhFYQ8$LKB*B1#GJ1rBL4Vs~M?>4ccCQmff858hM+zGEUEX?b3#IwR zLwlm3E?h-jxGK?Ce6@@A?h7LToPafE-=0p4=v<(U=J>fL3iD>-N{_m573Z#XaJIVx zAp}=?B50kcKxF8+lu;IFqiO9rgHnp98>22<#o6u-KL71Iq*f@cl1orIbXF6YGHRJ= z!Oj9-&)PanIA6&mPll8GTA_`}Skk*<(eCOE<&Tzpib#;rmy(kFBChmA=yM0~hd_AB z?|vWv0G95lI}!?J*BWCiWfHxj)*5B>upxCTqiX*F6*k#$8@-iC00000NkvXXu0mjf DdMq!f delta 930 zcmV;T16};I3FZfoQhx^>1PuohEEGBb00VPLL_t(o!@ZYXXdG1($A5S8v2D7YT2|7~ z7}7>1MbHXO!A5-2T4+HiL+FAKh!IgE_)>IU1OSW7~7pU7A z;+B!?U?;cq>urtW&CqM5R;o{oIy};72z?jF3*G__0pEqb`>Nvwf%IH|wd+g*U)k~dfjgQ;paY#h2vkDfowkHdSo;hx z3(U231nWpm*Y!t%{S9;81U_}VzyOZ}_gecE;BVXB-6?@5tklwQKLxzkkOQANUT_fj z8u%V~)(-UnTW$M#rz+@g==ZFX1N(qWz&F-(-ad~3kADKIz(48wju-S~U1|fH?bE<3 zq3`|z{0y80CV-dfBJnvOvnDVJJPhm%efM?83kZF8(&oxM@D6adopWeCDR)|m(;TP( zKh@U-i^b4)ryVbNE%e>xu2sSfh^5cvu9o7g(asSJI9@Pf<<>3~;B1z_W5DmX`!i+e;`0*PolrP<)f@iWi1Z_0mUi^Wf9fL$NrgY#a7yn%1LU{=x1Xr)E zpntWd*M6%FWt|1uXwLn%h*FA5RHby_C>P30d~p5?q*f@cP-cz5g#A_%SrwV>`Q=@S z9-d1RE>UasObGFx^F%AOF_}5N3HwhSpV@ckp0kLxWK5)FPjNR_udQ%BS|zb0VwIFd zmr5-Uoi2S;$PY{zV{*!9j4^1fQAVSUK^q%gRz^+z3yZvQX{0rAApigX07*qoM6N<$ Ef_+}PfdBvi diff --git a/images/icons/upload.png b/images/icons/upload.png index de70c73d0013edadbcac1cc104bc85cb982dd36e..24ff3617e07b606e642f5079d1bc27af89fb3f32 100644 GIT binary patch delta 1296 zcmV+r1@HQT3DF9WQhx{w1T8KzI5%bh00iDiL_t(o!?l-fOqFFA$A8bm;T(~d17U!N zSJ4C`0mCt0=2kg_=xq*2TJwWe!{~!wbg5f5by&vgOH0e8ZPterSy`@}%h^_Lh`M=D zmOzBS1hSO31Lx&=?)&ZoZ~#R(;PLli4qeY$MB(qq)&N zKuL~+RcSE++kelRfMH5@ooOV=ZsSl%Hc~2dUE{ZwJ8b*0fr?dWq|XbVp1??{m5mq1 zIINk>=;QM(40sKyUR*-ce}im3?qtov$7sJZ#0Lc#JhL#CYG)@$>N?o|>_Vc$LZ{q; z8P)mzbIm9T`wBAwNVd-*A<{~1>s=1lb+CKgVl-W&G=IlIX^w*}C+qp5BzsB%Gph4l zYoDOK$4y1eH3~E1cqJ>I{Y6Uvs4UFDD;3?nZmQ0=P`)yi+(dg|8Zf1zILk4t_7SxA z3~{BaZ$fS^cl5G6IhupTOQ~z`rM%k7JF6Cun;1oy)x!I~+#oAHlFy5m0`SB2?!XAR z4Z*RED}NZz;P{m`HlMhRWn2k;bLAG*S3Ai~vh(_~MDkOjsj2Vc=*2b?W5TF<`AGoU z?hbM2!cAU!Dk1PHkWx*kb0O7z%8UrJP+5>cL-zpXC!D;Imqc;)e2TN@1K{$Se0c6J zvK>*puq2+o(YXwuz^c>|ENq zCismgKP86zl$ep+x3hEYB1&@{pcK2$G-97);nP>M9&INC{JB4P;U-##~{lrwgsX&Qqbmn+=b8Zj2a=p?2Q zX={lOIk0|{^S$rC)}nUQD1ZU4iCI;G9)F_GDx|(aFR{B%5pJ~*s=HhTi)uqtW7BOy zNK7g47+$1ONF_0(V94j8t+(sA9;`hb@|pgTBHY>7y*Kh=#6au5~t} zX&N0p-AFmS1KlIXrJ$-nDoJfyJ%2(7`n)d6@`||D+03_>e!`RjA%#B$%SX;?TCkc- zq^%|1kcsb(3eFIwUnir^4JnXH1l8ZU($V7$YQn z!svV?1OQfiQubYhZEmSjN*79^ltN00P;#^(bqXa){|AiE3#_I7pMU@W00{s|MNUMn GLSTaHl7Th= delta 1087 zcmV-F1i<^z3W5ocQhx^>1Pn7PgVD|a00a+7L_t(o!?l-9XkA4V$A33T^V&3>D3LVS z?;31%(ITzjLIuT6p#`yo*oY{J(SlY?#6qJ8!-z_vbR+1ZezX`tOMSJVi!$9vbrJ2x zv~*)^ix$(mkkCm;^4`5O<0AK!H0I;I1mk@KuLLSl{_r8xkqSo0yt%r zJOR9%f?HeIQ)u%Ja0K{uP6}p7H9uv%0oXn*0uNgye}4w{3vC`1+GK$btdhR~7Wf$W z%_`ZN&VQy908gf=R!E%}fX}DRc}Zx~2J~AcKLgGQZJra_bOBeak{zkzCg4rr>rwzz zPs{Vl8P*J2CA)++52U9*YL)B*`clVrKo4*pI0^h%3V>oP2yL3JlG#*rPYG>K0q+A( z10z<+f`2A<09SzZWdmT9d_Cpedsz$?K0Kq%rcD++^U z6{DjotFP8Zw=Ii+h*g=(t1El=wGSNr?$~?)65G@KU{PJNJKF&KQ*ge!sejpq`pr1! zNxWks&f$Z{2T$zR930C}u;NJT?l~#2Jk{8(Uh;g&TrpiVCeV%Wx;`Rk>G>p%zveyXsl}>m*i>Pv4>072e~*jNEAg}8@_?} zo~ra;t+CuH@WIpn=LMW|+{}&Ax?>L)hX(oT{P!f@;k?6zNdP<3f3>JwMP^mz^6J>H zIam-}>?Z436h*h3$KK&XD4WyUY Add all + + true + @@ -76,32 +79,6 @@ - - - - - 0 - 0 - - - - - 22 - 0 - - - - Remove - - - - - - - Add - - - @@ -120,6 +97,29 @@ Remove all + + true + + + + + + + Remove + + + true + + + + + + + Add + + + true + @@ -179,6 +179,9 @@ CartoCSS + + true + @@ -186,6 +189,9 @@ SQL + + true + @@ -206,6 +212,9 @@ Cancel + + false + @@ -216,6 +225,9 @@ Create + + true + diff --git a/widgets/ListWidgets.py b/widgets/ListWidgets.py index c74d0fc..e33088e 100644 --- a/widgets/ListWidgets.py +++ b/widgets/ListWidgets.py @@ -53,21 +53,22 @@ def dragMoveEvent(self, event): def dropEvent(self, event): if isinstance(event.source(), CartoDBLayersListWidget): event.setDropAction(Qt.MoveAction) - # QListWidget.dropEvent(self, event) - for item in event.source().selectedItems(): - itemWidget = event.source().itemWidget(item) - newItemWidget = CartoDBLayerListItem(itemWidget.tableName, itemWidget.layer, itemWidget.size, itemWidget.rows) - newItem = event.source().takeItem(event.source().row(item)) - itemAt = self.itemAt(event.pos()) + if len(event.source().selectedItems()) > 0: + for item in event.source().selectedItems(): + itemWidget = event.source().itemWidget(item) + newItemWidget = CartoDBLayerListItem(itemWidget.tableName, itemWidget.layer, itemWidget.size, itemWidget.rows) + newItem = event.source().takeItem(event.source().row(item)) + itemAt = self.itemAt(event.pos()) - if itemAt is not None: - self.insertItem(self.row(itemAt), newItem) - else: - self.addItem(newItem) + if itemAt is not None: + self.insertItem(self.row(itemAt), newItem) + else: + self.addItem(newItem) - self.setItemWidget(newItem, newItemWidget) - self.setItemSelected(newItem, True) - # event.accept() + self.setItemWidget(newItem, newItemWidget) + self.setItemSelected(newItem, True) + + self.setFocus() def dropMimeData(self, index, mimedata, action): super(CartoDBLayersListWidget, self).dropMimeData(index, mimedata, action)