From ea0b2a60ba1687047c0418c60d9710a97d33edd0 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Thu, 12 Nov 2015 17:50:58 +0100 Subject: [PATCH] Small refactoring to have both View and Edit buttons for documents --- plugins/kolab_files/kolab_files.js | 40 ++++-- plugins/kolab_files/kolab_files.php | 1 + .../kolab_files/lib/kolab_files_engine.php | 114 ++++++++++-------- .../skins/larry/images/buttons.png | Bin 3401 -> 7648 bytes plugins/kolab_files/skins/larry/style.css | 5 +- .../skins/larry/templates/docedit.html | 10 +- .../skins/larry/templates/files.html | 3 +- plugins/kolab_files/skins/larry/ui.js | 2 +- 8 files changed, 111 insertions(+), 64 deletions(-) diff --git a/plugins/kolab_files/kolab_files.js b/plugins/kolab_files/kolab_files.js index 13bcca53..d6ad0774 100644 --- a/plugins/kolab_files/kolab_files.js +++ b/plugins/kolab_files/kolab_files.js @@ -108,14 +108,17 @@ window.rcmail && window.files_api && rcmail.addEventListener('init', function() kolab_files_init(); - if (rcmail.env.action == 'open') { + if (rcmail.env.action == 'open' || rcmail.env.action == 'edit') { rcmail.enable_command('files-get', 'files-delete', rcmail.env.file); - if (rcmail.env.file_data.viewer && rcmail.env.file_data.viewer.manticore) + if (rcmail.env.action == 'edit' && rcmail.env.file_data.viewer && rcmail.env.file_data.viewer.manticore) manticore = new manticore_api({ iframe: $('#fileframe').get(0), export_menu: rcmail.gui_objects.exportmenu ? $('ul', rcmail.gui_objects.exportmenu).get(0) : null, title_input: $('#document-title').get(0), + members_list: $('#members').get(0), + photo_url: '?_task=addressbook&_action=photo&_email=%email', + photo_default_url: rcmail.env.photo_placeholder, ready: function(data) { manticore_init(); }, set_busy: function(state, message) { return rcmail.set_busy(state, message ? 'kolab_files.' + message : ''); }, hide_message: function(id) { return rcmail.hide_message(id); }, @@ -825,6 +828,7 @@ function kolab_files_list_select(list) else rcmail.env.viewer = 0; + rcmail.enable_command('files-edit', (rcmail.env.viewer & 4) == 4); rcmail.enable_command('files-open', rcmail.env.viewer); }; @@ -910,11 +914,10 @@ function kolab_files_frame_load(frame) } catch (e) {}; - if (rcmail.file_editor) - rcmail.enable_command('files-edit', true); - - rcmail.enable_command('files-print', (rcmail.file_editor && rcmail.file_editor.printable) || - (rcmail.env.file_data && /^image\//i.test(rcmail.env.file_data.type))); + rcmail.enable_command('files-edit', rcmail.file_editor + || (rcmail.env.file_data.viewer && rcmail.env.file_data.viewer.manticore)); + rcmail.enable_command('files-print', (rcmail.file_editor && rcmail.file_editor.printable) + || (rcmail.env.file_data && /^image\//i.test(rcmail.env.file_data.type))); // detect Print button and check if it can be accessed try { @@ -1143,6 +1146,16 @@ rcube_webmail.prototype.files_edit = function() this.file_editor.enable(); this.enable_command('files-save', true); } + else if (this.env.file) { + var viewer = file_api.file_type_supported(this.env.file_data.type, this.env.files_caps); + file_api.file_open(this.env.file, viewer, 'edit', true); + } + else if (!this.env.action) { + var files = kolab_files_selected(); + + if (files.length == 1) + file_api.file_open(files[0], this.env.viewer, 'edit'); + } }; rcube_webmail.prototype.files_save = function() @@ -2657,10 +2670,17 @@ function kolab_files_ui() }; // open file in new window, using file API viewer - this.file_open = function(file, viewer) + this.file_open = function(file, viewer, action, local) { - var href = '?' + $.param({_task: 'files', _action: 'open', file: file, viewer: viewer || 0}); - rcmail.open_window(href, false, true); + var href = '?' + $.param({_task: 'files', _action: action || 'open', file: file, viewer: viewer || 0}); + + if (rcmail.env.extwin) + href += '&_extwin=1'; + + if (local) + location.href = href; + else + rcmail.open_window(href, false, true); }; // save file diff --git a/plugins/kolab_files/kolab_files.php b/plugins/kolab_files/kolab_files.php index 9ff9a2a3..8efad587 100644 --- a/plugins/kolab_files/kolab_files.php +++ b/plugins/kolab_files/kolab_files.php @@ -49,6 +49,7 @@ class kolab_files extends rcube_plugin $this->register_action('index', array($this, 'actions')); $this->register_action('prefs', array($this, 'actions')); $this->register_action('open', array($this, 'actions')); + $this->register_action('edit', array($this, 'actions')); // we use libkolab::http_request() from libkolab with its configuration $this->require_plugin('libkolab'); diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php index 611af95c..add82156 100644 --- a/plugins/kolab_files/lib/kolab_files_engine.php +++ b/plugins/kolab_files/lib/kolab_files_engine.php @@ -892,56 +892,16 @@ class kolab_files_engine */ protected function action_open() { - $file = rcube_utils::get_input_value('file', rcube_utils::INPUT_GET); - $viewer = intval($_GET['viewer']); + $this->rc->output->set_env('files_caps', $_SESSION['kolab_files_caps']); + $this->file_opener(intval($_GET['viewer']) & ~4); + } - // get file info - $token = $this->get_api_token(); - $request = $this->get_request(array( - 'method' => 'file_info', - 'file' => $file, - 'viewer' => $viewer, - ), $token); - - // send request to the API - try { - $response = $request->send(); - $status = $response->getStatus(); - $body = @json_decode($response->getBody(), true); - - if ($status == 200 && $body['status'] == 'OK') { - $this->file_data = $body['result']; - } - else { - throw new Exception($body['reason']); - } - } - catch (Exception $e) { - rcube::raise_error(array( - 'code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, - 'message' => $e->getMessage()), - true, true); - } - - $this->file_data['filename'] = $file; - - $this->plugin->add_label('filedeleteconfirm', 'filedeleting', 'filedeletenotice'); - - // register template objects for dialogs (and main interface) - $this->rc->output->add_handlers(array( - 'fileinfobox' => array($this, 'file_info_box'), - 'filepreviewframe' => array($this, 'file_preview_frame'), - )); - - $placeholder = $this->rc->output->asset_url('program/resources/blank.gif'); - - // this one is for styling purpose - $this->rc->output->set_env('extwin', true); - $this->rc->output->set_env('file', $file); - $this->rc->output->set_env('file_data', $this->file_data); - $this->rc->output->set_env('photo_placeholder', $placeholder); - $this->rc->output->set_pagetitle(rcube::Q($file)); - $this->rc->output->send('kolab_files.' . ($viewer & 4 ? 'docedit' : 'filepreview')); + /** + * Handler for file open action + */ + protected function action_edit() + { + $this->file_opener(intval($_GET['viewer'])); } /** @@ -1226,6 +1186,62 @@ class kolab_files_engine $this->rc->output->send(); } + /** + * Handler for file open/edit action + */ + protected function file_opener($viewer) + { + $file = rcube_utils::get_input_value('file', rcube_utils::INPUT_GET); + + // get file info + $token = $this->get_api_token(); + $request = $this->get_request(array( + 'method' => 'file_info', + 'file' => $file, + 'viewer' => $viewer, + ), $token); + + // send request to the API + try { + $response = $request->send(); + $status = $response->getStatus(); + $body = @json_decode($response->getBody(), true); + + if ($status == 200 && $body['status'] == 'OK') { + $this->file_data = $body['result']; + } + else { + throw new Exception($body['reason']); + } + } + catch (Exception $e) { + rcube::raise_error(array( + 'code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, + 'message' => $e->getMessage()), + true, true); + } + + $this->file_data['filename'] = $file; + + $this->plugin->add_label('filedeleteconfirm', 'filedeleting', 'filedeletenotice'); + + // register template objects for dialogs (and main interface) + $this->rc->output->add_handlers(array( + 'fileinfobox' => array($this, 'file_info_box'), + 'filepreviewframe' => array($this, 'file_preview_frame'), + )); + + $placeholder = $this->rc->output->asset_url('program/resources/blank.gif'); + + // this one is for styling purpose + $this->rc->output->set_env('extwin', true); + $this->rc->output->set_env('file', $file); + $this->rc->output->set_env('file_data', $this->file_data); + $this->rc->output->set_env('photo_placeholder', $placeholder); + $this->rc->output->set_pagetitle(rcube::Q($file)); + $this->rc->output->send('kolab_files.' . ($viewer & 4 ? 'docedit' : 'filepreview')); + } + /** * Returns mimetypes supported by File API viewers */ diff --git a/plugins/kolab_files/skins/larry/images/buttons.png b/plugins/kolab_files/skins/larry/images/buttons.png index abd9b5484fe32792f6983d59732e23d20e4d02e2..a1dbccf5168a6bca459e3bacdb954e66358bd873 100644 GIT binary patch literal 7648 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 QNia4?aOZ@(6nqp^> z?14X~z-)fat>z1_q+uYShV(?Oa5ytS{;IZn$<)ZmXxz;=em>#sG7R9X7BR1Q%Z@U{ zou^|gz;R2!jg#dOR8U3@WlvNo)KTgv)QENR(zUtck~Gl_0sRVxCmrrXM3zpm09pnrgSd>rlZE$KQ8@{ zzmvMzz4~Dzj*H^#>9=_uAT-wFaLd&%MA(2*1@OzUoZYZQU!mNY;=Szi=Jt$YZc!j! zakm-wljXL*02Pqk@sT1ePLTCr5f`yHVKC6M_sxII)mThcF^x13_XCx!M_CZC7TNh_ z#dcfUyW%yzj6Pq-!5kS0_lEOmqou@oCa=$+`$QC=^2=As6v}e4%w9hLe7}|;^9oN6 z9bzuMrc8yu`nRpt%vCv!@FW#G1J=5nY48vk;`PoS!ZUW2H8o8y@G~Sb2}R9pY1;Bf zE0_>-40VJ?S+m>%YxRaGS_R7Tv@*r%b5)h_=Lrxs1b1YPjz0V{NAf*Dp5*v6MA6(h zH51_KG8(8fP{-3c%~&uyHsAG+#TU=T=?8FiUa|_2)>Fsz7yFHxUQI7!1{|{o_b;La z`}}T%nxGkh@=uOF!A_@eP)Q?&1R1KBFLeLW3_y90c4iy*Zz}{a^oeE7S*nw&w7fzw zP_onc+Qk+-UrI}QLdgLssqj-ACmLcv90Vyzn0fMcYp&I0X)sr=@YX%nq;rmdUsrKr zsh-VqEP$A16YP^*<#*(e5AakY;6GcXut~YI4c}(bKu_2yP}(Q_els|eT_)gPZd&u_ z;a8sPkge&uG=}5sV1^%%E=uJEjC6%*O|c9V9F2ji^SqW0(lg}O<+6bAgRX}wzu$#| z)#zf1pxyKdnB-$vft=%;>j7l5fkP^Tbru=s1D>#ktlWEGuaQ#+BmG)SF zS%4L5nb7enB&3ZvZQjI?{_0it8vWmLs3LQ;PeR(tG14pdxm*}zBlS=@XR2HRxx@du z$4!WD^WO9R(+~6?#wlwuBwz$3-|5*UBqp{8EWeK9Y&!ju&1nqbr2qlOxnfwY%gq#j zqW>MPf66s1Knd`FfQynDLZ1822R@&lUEVFGOevaw-J?pHwG4qz7p zVrO1@qhG!(hFV_4ua4pR89KJW3pUVa2SB?;rxr9`2DSVlQHGD(XIhR g``>2&^_nCDljJ6A?e+?I7YowS&{zMYY8~}|0J@pS@c;k- literal 3401 zcmXX|cRZVI_YWy0W?NOO9(z4n!GjvLSBwy~iw3br5o%QISVdx#*gPS$HA=Orlva#V zTUA%A)Na*_4#Ly-dVcTk{Bh;n=RVi>e9!ls`}0YbEz*n&CIo{(AY2G@V>|FG4uLSK zvq6FPu8Lz60%1O|wX!z>kH7!VfMa1{0Zw3aI{kk>7K_cu$N=wcY-}toErDbBaQXW6 z>mUx&TwPs_jg9}885I?ULZLt~H#gVM&o4ec9twpP6&1;nM&sh*($mxb#f3nOENzaC zjxEREN zg@uIyK7oOOPEJnA$;qCcp3Kb5U0q$^6~MG@dINAKCMLim$e~iH(b3UaSy_gLh9I)P zzwhDU0muL!q=6obitgIm+nbx4g9wR4>ged`@9&4f{*~R?+1ba(XL)%UWTMe%P)j(Kv7y*yQ9SpF1ufAOPS4&HxQm z2NwZ8xCKT)CX=V8ra*UcZ99^b#Y;_epavjt5!V0`4h{}hS63Yd4$fL&Ky`RwUv+gg zm#WFy+L~1d9f)tzFa!LYoE$SVGf=CvwDjrIr_IgHpcc>#j0PTd$M(T29*^(q>jN!p zZf=4h(r7f$5n#ouW->N529K{&POJ?M4%XAtvu>C~walB7dH@0rhXcBuoScA;Kx;tB zkdTmwhzNit_LPyBmZcQCS@ogJ_S?(XiszP?^wUSP6zc6RXR49ype zU%!5V4Fu}N#>U>clLM9qa0AR89Ub@f_Q0YN2t>fg?$xnG7Xv8i@9z)TS_~a8EiLKw zAIo<$wzs#zl)(Z6!AnX?OifL>@4uJ=5)Vb%A+JGXwe)$b`{wme&rmMDNMf0vM4r2& z4~G`$!y5{bQvZCLnU2#GIZ=Lr3Wivh@Oi^H`t)}KKAtofm*V73lL8nbmPf+_> zDa14#3s^cOZz+3g`i&P5SG+|F?16&-2FyYr(OD z4?FIVh`xuj!<;rHCDt`q^{TL6z0=f340aveiga&Gi%U;-M(*Ib4M$bg`9_*LUMVC9 zo2z--?(mTx_d48n;k=h`nH2ff%7dXnuIS+1%kxN;cD381b~;T7lN3n~%DWAhkRi>* z&ji7(pF%TFa0_GmW!AW{0+Fzsqo3k)AAY_r7fiT}W$cdy;#yFRA0GKl3jH;{O$(rj zb1lU^HWVR;s*%I7v(MNy>Md(2<+($FQJSVme=EfS%`U@pwfTj9J&ApaO6C&Z+JAmK zH0^xnOy3*mF8%t&!8Cj6*I=5%Q@{y4lzWx2V1 z=afeuZhb}gM8D|r96DYq#&3Idy}PFY8C!Tbs}%mmT$9AEhsR($%R3Z&mAI`2W^Dx zDsqMMIP2=d&#;-4#soLbg@y4-k!}?@c79tXS+f54DrC@ zgTT<;%UesrnS-z_?^s?xmFrD1Rc$g(_uRT*Ml&)q&!VlWnUU^3Gc`OgurZi(usP$PkYxzH?10&H z9nY6C4PTxSFue3d5uMh-K@Pa|DZQ9N{eXus*;D-=pN=EJ*z6PyU&B7IO=oh6Hu|I` zztk^kG50na>@E4A!R+(Rr{ZtG>Ft`GKCg>S__BB2*kIgx zVy7(>H=R|4MxBJ#mxSv+dL8b*T!tGoz2yl_9a%09w|rUgdh%Ivj_}e=pSLyAR#~Wf zt>z1t-RE-Oc_N=k`aZC|TItP>51c#KU}9B%mO`y?U>wa=`941yDVkeWZJ(6WmRVu8 z(4y?AODb8s_dtq>#{T`MiRLBQ)L~BJaHA;A)}A@tQkiQb-ThnF2+nuKQB+p+TKb+8 z69Hu=1x43im1znWxW2?6qyf>8Quy=C*Vm#it&+Ao=!L5@k{YDr>jFk1>>1j(dR%iK zdosJ3(WTirM<$BO`9-el@W-%!t2Lp`-L3f@Q!Xmrw&urlg>PM|J406bWY<(n8_V9$ zQ4`m6yPMd=)r_pu9xF#=H?dn`DJJB8Cm!L2fXKnq+$r~`*zNy06*tdhC zEA}Fhs-X?tD<~_72w=ixStyXdhJ9*PlJ8~l`JMSI{;=u|?|BtR2UfFzVVf+z^F*OX zMyZml*&G-$_v(XmR|wWy3Wfdb)7_Bpj2w6K7*0&lKXp`$*7+qUIa0;+f=5)o^Xx#OUx{S@s^-SZ2wHDXX@C zXGIn-3%hc@{gPG3dg)9j!GI14GkbDL{t>}blF7U>mBwPs?i$D$PtN2PYIY{&h59f- zO&~<+vz!)Z`Sm0-8nU)&)7uG<|qqaUOJj8OJV%zo8#9nCc5WQnz-q<<#YUyNoD3D3=W_b>$iOc25vw?h+ zl?bu&zVOd;wC>$#nf(Vnv4bKuzKQfJ$MtySV55)uMr(SwqnMxziS&UJMs&&J)=JHf zJ?gDHdcCBf#Vd#ZB=qKg*&Z*}>D6<2A#m|}Vw&H2K$%0VjK5B6^{(QpPvdg_Jz2E4 z8jaWWKidq4nhw7&>ipcL{Il=IJk*oVqWNZ=mHAkc+X1uAAuYG*`|p|3|4f2VG@VjR zvL;gf?DKYV!bNl`X?fCh&qgpW(84zw!b$fhSeerZ^W?u~*E?%})GCPSEY~EAoRw4` zLvhW=`DO{{vPd*aknXLOT$M5klGggBVnbmJl!a*-0GU(RH{nWeOT+N*dzA_BS(e9VYu2vj`Af- zul)Fj_ - +