diff --git a/modoboa/extensions/amavis/sql_listing.py b/modoboa/extensions/amavis/sql_listing.py index af503c83a..71c2cd5aa 100644 --- a/modoboa/extensions/amavis/sql_listing.py +++ b/modoboa/extensions/amavis/sql_listing.py @@ -18,20 +18,38 @@ class Qtable(tables.Table): styles = "table-condensed" idkey = "mailid" + selection = tables.SelectionColumn( + "selection", safe=True, width='5px', header=None, sortable=False + ) type = tables.Column( "type", align="center", width="30px", sort_order="type", safe=True ) - score = tables.Column("score", label=ugettext_lazy("Score"), limit=6, - sort_order="score") - rstatus = tables.ImgColumn("rstatus", width='25px', sortable=False) - from_ = tables.Column("from", label=ugettext_lazy("From"), limit=30, - sort_order="from") - subject = tables.Column("subject", label=ugettext_lazy("Subject"), limit=40, - sort_order="subject") - time = tables.Column("date", label=ugettext_lazy("Date"), sort_order="date") - to = tables.Column("to", label=ugettext_lazy("To"), sort_order="to") - - cols_order = [] + rstatus = tables.ImgColumn( + "rstatus", width='25px', sortable=False + ) + score = tables.Column( + "score", label=ugettext_lazy("Score"), limit=6, + sort_order="score", cssclass="openable" + ) + to = tables.Column( + "to", label=ugettext_lazy("To"), sort_order="to", cssclass="openable" + ) + from_ = tables.Column( + "from", label=ugettext_lazy("From"), limit=30, + sort_order="from", cssclass="openable" + ) + subject = tables.Column( + "subject", label=ugettext_lazy("Subject"), limit=40, + sort_order="subject", cssclass="openable" + ) + time = tables.Column( + "date", label=ugettext_lazy("Date"), sort_order="date", + cssclass="openable" + ) + + cols_order = [ + 'selection', 'type', 'rstatus', 'score', 'to', 'from_', 'subject', 'time' + ] def parse_type(self, value): color = 'important' if value in ['S', 'V'] else 'warning' @@ -254,8 +272,6 @@ class SQLlisting(EmailListing): reset_wm_url = True def __init__(self, user, msgs, filter, **kwargs): - Qtable.cols_order = ['type', 'score', 'rstatus', 'to', 'from_', - 'subject', 'time'] self.mbc = SQLconnector(msgs, filter) super(SQLlisting, self).__init__(**kwargs) self.show_listing_headers = True diff --git a/modoboa/extensions/amavis/static/amavis/css/quarantine.css b/modoboa/extensions/amavis/static/amavis/css/quarantine.css index 2f7575752..2ee4aeab5 100644 --- a/modoboa/extensions/amavis/static/amavis/css/quarantine.css +++ b/modoboa/extensions/amavis/static/amavis/css/quarantine.css @@ -41,6 +41,10 @@ thead tr { z-index: 1; } +td > input[type=checkbox] { + margin: 0; +} + td[name=type] span { cursor: pointer; } @@ -49,6 +53,10 @@ td.unseen { font-weight: bold; } -td.pending { +td[class*=pending] { font-style: italic; +} + +td[class*=openable] { + cursor: pointer; } \ No newline at end of file diff --git a/modoboa/extensions/amavis/static/amavis/js/quarantine.js b/modoboa/extensions/amavis/static/amavis/js/quarantine.js index cda5304a9..bcb871eb1 100644 --- a/modoboa/extensions/amavis/static/amavis/js/quarantine.js +++ b/modoboa/extensions/amavis/static/amavis/js/quarantine.js @@ -56,7 +56,7 @@ Quarantine.prototype = { }, listen: function() { - $(document).on("dblclick", "tbody>tr", $.proxy(this.viewmail_loader, this)); + $(document).on("click", "td[class*=openable]", $.proxy(this.viewmail_loader, this)); $(document).on("click", "a[name=selectmsgs]", $.proxy(this.selectmsgs, this)); $(document).on("click", "a[name=release-multi]", $.proxy(this.release_selection, this)); @@ -105,9 +105,10 @@ Quarantine.prototype = { $("#emails").htmltable("clear_selection"); return; } - $("td[name=type]").each(function() { - var $this = $(this); - $("#emails").htmltable("select_row", $this.parent()); + $("td[name*=selection]").each(function() { + var $input = $(this).children('input'); + $input.prop('checked', true); + $('#emails').htmltable('select_row', $(this).parent()); }); }, @@ -122,7 +123,9 @@ Quarantine.prototype = { $("td[name=type]").each(function() { var $this = $(this); if ($this.find('span').html().trim() == type) { - $("#emails").htmltable("select_row", $this.parent()); + var $input = $this.parent().children('td[name=selection]').children('input'); + $input.prop('checked', true); + $('#emails').htmltable('select_row', $this.parent()); counter++; } }); @@ -253,12 +256,14 @@ Quarantine.prototype = { activate_buttons: function($tr) { $("a[name=release-multi]").removeClass('disabled'); $("a[name=delete-multi]").removeClass('disabled'); + $("#selectall").prop('checked', true); }, deactivate_buttons: function($tr) { if (!this.htmltable.current_selection().length) { $("a[name=release-multi]").addClass('disabled'); $("a[name=delete-multi]").addClass('disabled'); + $("#selectall").prop('checked', false); } }, diff --git a/modoboa/extensions/amavis/views.py b/modoboa/extensions/amavis/views.py index 07be93a5c..1f46ad929 100644 --- a/modoboa/extensions/amavis/views.py +++ b/modoboa/extensions/amavis/views.py @@ -25,7 +25,7 @@ from .models import Msgrcpt def empty_quarantine(request): content = "
%s
" % _("Empty quarantine") - ctx = getctx("ok", level=2, listing=content, navbar="") + ctx = getctx("ok", level=2, listing=content) return render_to_json_response(ctx) @@ -75,19 +75,13 @@ def _listing(request): return empty_quarantine(request) content = lst.fetch(request, page.id_start, page.id_stop) -<<<<<<< HEAD - paginbar = pagination_bar(page) - ctx = getctx("ok", listing=content, paginbar=paginbar, page=page.number) + ctx = getctx( + "ok", listing=content, paginbar=pagination_bar(page), page=page.number + ) if request.session.get('location', 'listing') != 'listing': ctx['menu'] = quar_menu() request.session['location'] = 'listing' - return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") -======= - navbar = lst.render_navbar(page, "listing/?") - ctx = getctx("ok", listing=content, navbar=navbar, - menu=quar_menu(request.user)) return render_to_json_response(ctx) ->>>>>>> master @login_required @@ -155,12 +149,8 @@ def viewmail(request, mail_id): """).render(Context({"url": reverse(getmailcontent, args=[mail_id])})) menu = viewm_menu(mail_id, rcpt) ctx = getctx("ok", menu=menu, listing=content) -<<<<<<< HEAD request.session['location'] = 'viewmail' - return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") -======= return render_to_json_response(ctx) ->>>>>>> master @login_required diff --git a/modoboa/extensions/webmail/lib.py b/modoboa/extensions/webmail/lib.py index b910dc546..d662d4fc9 100644 --- a/modoboa/extensions/webmail/lib.py +++ b/modoboa/extensions/webmail/lib.py @@ -26,22 +26,29 @@ class WMtable(tables.Table): tableid = "emails" styles = "table-condensed" idkey = "imapid" - select = tables.ImgColumn( - "select", cssclass="draggable left", width="2%", + drag = tables.ImgColumn( + "drag", cssclass="draggable left", width="1%", defvalue="%spics/grippy.png" % settings.STATIC_URL, header="" ) - flags = tables.ImgColumn("flags", width="4%") + selection = tables.SelectionColumn( + "selection", safe=True, width='1%', header=None, sortable=False + ) + flags = tables.ImgColumn("flags", width="2%") withatts = tables.ImgColumn("withatts", width="2%") subject = tables.Column( - "subject", label=ugettext_lazy("Subject"), width="50%", limit=60 + "subject", label=ugettext_lazy("Subject"), width="50%", limit=60, + cssclass="openable" ) from_ = tables.Column( - "from", width="20%", label=ugettext_lazy("From"), limit=30 + "from", width="20%", label=ugettext_lazy("From"), limit=30, + cssclass="openable" + ) + date = tables.Column( + "date", width="15%", label=ugettext_lazy("Date"), cssclass="openable" ) - date = tables.Column("date", width="15%", label=ugettext_lazy("Date")) - cols_order = ["select", "withatts", "flags", "subject", "from_", "date"] + cols_order = ["drag", "selection", "withatts", "flags", "subject", "from_", "date"] def parse(self, header, value): if value is None: diff --git a/modoboa/extensions/webmail/static/webmail/css/webmail.css b/modoboa/extensions/webmail/static/webmail/css/webmail.css index 82adf1cef..a33f6ec01 100644 --- a/modoboa/extensions/webmail/static/webmail/css/webmail.css +++ b/modoboa/extensions/webmail/static/webmail/css/webmail.css @@ -202,4 +202,15 @@ div.expanded { #folders2 li { position: relative; +} + +/* + * Table + */ +td > input[type=checkbox] { + margin: 0; +} + +td[class*=openable] { + cursor: pointer; } \ No newline at end of file diff --git a/modoboa/extensions/webmail/static/webmail/js/webmail.js b/modoboa/extensions/webmail/static/webmail/js/webmail.js index d3440efd7..17659db0f 100644 --- a/modoboa/extensions/webmail/static/webmail/js/webmail.js +++ b/modoboa/extensions/webmail/static/webmail/js/webmail.js @@ -76,7 +76,7 @@ Webmail.prototype = { $(document).on("click", "a[name=editmbox]", $.proxy(this.edit_mbox, this)); $(document).on("click", "a[name=removembox]", $.proxy(this.remove_mbox, this)); - $(document).on("dblclick", "tbody>tr", $.proxy(this.viewmail_loader, this)); + $(document).on("click", "td[class*=openable]", $.proxy(this.viewmail_loader, this)); $(document).on("click", "a[name=reply]", $.proxy(this.reply_loader, this)); $(document).on("click", "a[name=replyall]", $.proxy(this.reply_loader, this)); @@ -989,7 +989,7 @@ Webmail.prototype = { init_draggables: function() { var plug = this; - $("td[name=select]").draggable({ + $("td[name=drag]").draggable({ opacity: 0.8, helper: function(e) { var $this = $(this); diff --git a/modoboa/static/js/jquery.htmltable.js b/modoboa/static/js/jquery.htmltable.js index 6ee6daf2e..1a185552d 100644 --- a/modoboa/static/js/jquery.htmltable.js +++ b/modoboa/static/js/jquery.htmltable.js @@ -10,6 +10,7 @@ this.$element = $(element); this.options = $.extend({}, $.fn.htmltable.defaults, options); this.shift_pressed = false; + this.ctrl_pressed = false; this.last_selection = null; this.prev_dir = null; this.listen(); @@ -26,8 +27,8 @@ listen: function() { $(document) - .off("click", "tbody>tr") - .on("click", "tbody>tr", + .off("change", "tbody input[type=checkbox]") + .on("change", "tbody input[type=checkbox]", $.proxy(this.toggle_select, this)); $(document).on("keydown", "body", $.proxy(this.keydown, this)); $(document).on("keyup", "body", $.proxy(this.keyup, this)); @@ -36,11 +37,13 @@ _toggle_select: function($tr) { this.last_selection = $tr; if ($tr.hasClass(this.options.tr_selected_class)) { + $tr.children('td[name=selection]').children('input').prop('checked', false); $tr.removeClass(this.options.tr_selected_class); if (this.options.tr_unselected_event != undefined) { this.options.tr_unselected_event($tr); } } else { + $tr.children('td[name=selection]').children('input').prop('checked', true); $tr.addClass(this.options.tr_selected_class); if (this.options.tr_selected_event != undefined) { this.options.tr_selected_event($tr); @@ -49,10 +52,13 @@ }, toggle_select: function(e) { - e.preventDefault(); - var $tr = $(e.target).parent(); + var $tr = $(e.target).parents('tr'); if (this.shift_pressed && this.last_selection) { + if ($tr.is(this.last_selection)) { + $tr.children('td[name=selection]').children('input').prop('checked', true); + return; + } var itfunc = ($tr.index() >= this.last_selection.index()) ? "next" : "prev"; var $curtr = null; @@ -70,6 +76,8 @@ } this.prev_dir = itfunc; return; + } else if (!this.ctrl_pressed && (!this.last_selection || !this.last_selection.is($tr))) { + this.clear_selection(); } this._toggle_select($tr); }, @@ -86,7 +94,9 @@ * Cancel the current selection */ clear_selection: function() { + this.last_selection = null; this.current_selection().removeClass(this.options.tr_selected_class); + $("tbody input[type=checkbox]").prop('checked', false); }, /* @@ -94,6 +104,7 @@ */ select_row: function($row) { $row.addClass(this.options.tr_selected_class); + }, keydown: function(e) { @@ -102,6 +113,9 @@ e.preventDefault(); this.shift_pressed = true; break; + case 17: + this.ctrl_pressed = true; + break; } }, @@ -111,6 +125,9 @@ e.preventDefault(); this.shift_pressed = false; break; + case 17: + this.ctrl_pressed = false; + break; } } };