'type' => 'special'
);
-// Message flags - system defaults
-// This entry should normally never be changed. It provides the base flags
-// for all users. Flags specific to a certain user should be defined in
-// 'msgflags_user'.
-$_prefs['msgflags'] = array(
- // Format:
- // KEY: Flag name
- // VALUE: Array with the following entries
- // 'a' - (string) [abbreviation] The abbreviation used in
- // the mobile (mimp) view.
- // DEFAULT: Don't show flag
- // 'b' - (string) [background] The CSS background color
- // DEFAULT: Use value of 'msgflags_color'
- // 'c' - (string) [class] The CSS background class (used to
- // display status icon).
- // NO DEFAULT (entry required)
- // 'd' - (boolean) [delete] If true, entry can be deleted.
- // DEFAULT: false
- // 'l' - (string) [label] The flag text label.
- // NO DEFAULT (entry required)
- // 't' - (string) [type] The flag type:
- // 'atc' - Attachment information
- // 'imap' - IMAP system flags (not settable by user)
- // 'imapp' - IMAP flags (personal flags - created by user
- // through the prefs interface)
- // 'imapu' - IMAP system flags (settable by user)
- // 'imp' - IMP defined flags
- // NO DEFAULT (entry required)
- 'value' => json_encode(array(
- // Static internal imp flags (i.e. status icons)
- // THESE ENTRIES MUST NOT BE DELETED
- 'personal' => array(
- 'a' => '+',
- 'c' => 'flagPersonal',
- 'l' => _("Personal"),
- 't' => 'imp'
- ),
- 'highpri' => array(
- 'a' => '!',
- 'b' => '#fcc',
- 'c' => 'flagHighpriority',
- 'l' => _("High Priority"),
- 't' => 'imp'
- ),
- 'lowpri' => array(
- 'a' => '0',
- 'c' => 'flagLowpriority',
- 'l' => _("Low Priority"),
- 't' => 'imp'
- ),
-
- // Attachment flags
- // THESE ENTRIES MUST NOT BE DELETED
- 'signed' => array(
- 'c' => 'flagSignedmsg',
- 'l' => _("Message is Signed"),
- 't' => 'atc'
- ),
- 'encrypt' => array(
- 'c' => 'flagEncryptmsg',
- 'l' => _("Message is Encrypted"),
- 't' => 'atc'
- ),
- 'attach' => array(
- 'c' => 'flagAttachmsg',
- 'l' => _("Message has Attachments"),
- 't' => 'atc'
- ),
-
- // IMAP flags
- // KEY: IMAP flag as it exists on the IMAP server
- // VALUES (additional to base values):
- // 'n' - (boolean) [NOT match] Don't match the flag.
- // DEFAULT: false
-
- // System IMAP flags (RFC 3501 [2.3.2])
- '\\answered' => array(
- 'a' => 'r',
- 'b' => '#cfc',
- 'c' => 'flagAnswered',
- 'l' => _("Answered"),
- // By default, this flag is not settable by the user - it is
- // automatically set when a message is replied to.
- 't' => 'imap'
- ),
- '\\draft' => array(
- 'a' => 'd',
- 'c' => 'flagDraft',
- 'l' => _("Draft"),
- // By default, this flag is not settable by the user - it is
- // automatically set/reset when a message is drafted/finished.
- 't' => 'imap'
- ),
- '\\deleted' => array(
- 'a' => 'D',
- 'b' => '#999',
- 'c' => 'flagDeleted',
- 'l' => _("Deleted"),
- // By default, this flag is not settable by the user - it is
- // handled via the Delete/Undelete links.
- 't' => 'imap'
- ),
- '\\seen' => array(
- 'a' => 'N',
- 'b' => '#eef',
- 'c' => 'flagUnseen',
- 'l' => _("Unseen"),
- 'n' => true,
- 't' => 'imapu'
- ),
- '\\flagged' => array(
- 'a' => '*',
- 'b' => '#fcc',
- 'c' => 'flagFlagged',
- 'l' => _("Flagged for Followup"),
- 't' => 'imapu'
- ),
-
- // Forwarded flag (RFC 5550 [5.9])
- '$forwarded' => array(
- 'a' => 'F',
- 'b' => '#bfdfdf',
- 'c' => 'flagForwarded',
- 'l' => _("Forwarded"),
- // Pursuant to RFC, this flag SHOULD NOT be changed by the user
- 't' => 'imap'
- ),
- ))
-);
-
-// Message flags - user specific
// This array contains the list of flags created by the user through the
-// flags UI. Additionally, an admin can define default non-system flags
-// for a user in this preference.
-// See the 'msgflags' preference for the format of this value.
-$_prefs['msgflags_user'] = array(
- // 'value' = json_encode(array())
- 'value' => '[]'
-);
-
-// The default color to use for flags that don't require row highlighting.
-$_prefs['msgflags_color'] = array(
- 'value' => '#ddd'
+// flags UI, and any modifications to the built-in system flags.
+$_prefs['msgflags'] = array(
+ // 'value' = serialize(array())
+ 'value' => 'a:0:{}'
);
// Show all flags (including flags set by other mail programs)?
case 'sendMessage':
if (this.is_popup && DimpCore.base) {
- if (d.reply_type) {
- DimpCore.base.DimpBase.flag(d.reply_type == 'forward' ? '$forwarded' : '\\answered', true, { uid: d.uid, mailbox: d.reply_folder, noserver: true });
+ if (d.flag) {
+ DimpCore.base.DimpBase.flagCallback(d);
}
if (d.mailbox) {
}
if (d.log) {
- DimpCore.base.DimpBase.updateMsgLog(d.log, { uid: d.uid, mailbox: d.reply_folder });
+ DimpCore.base.DimpBase.updateMsgLog(d.log, { uid: d.uid, mailbox: d.mbox });
}
if (!DIMP.conf_compose.qreply) {
// r = ViewPort row data
msgWindow: function(r)
{
- this.updateSeenUID(r, 1);
var url = DIMP.conf.URI_MESSAGE;
url += (url.include('?') ? '&' : '?') +
$H({ folder: r.view,
if (r.flag) {
r.flag.each(function(a) {
var ptr = DIMP.conf.flags[a];
- if (ptr.p) {
+ if (ptr.u) {
if (!ptr.elt) {
/* Until text-overflow is supported on all
* browsers, need to truncate label text
}
r.subjectdata += ptr.elt;
} else {
- if (!ptr.elt) {
- ptr.elt = '<div class="iconImg msgflags ' + ptr.c + '" title="' + ptr.l + '"></div>';
- }
- r.status += ptr.elt;
+ if (ptr.c) {
+ if (!ptr.elt) {
+ ptr.elt = '<div class="iconImg msgflags ' + ptr.c + '" title="' + ptr.l + '"></div>';
+ }
+ r.status += ptr.elt;
- r.VP_bg.push(ptr.c);
+ r.VP_bg.push(ptr.c);
+ }
if (ptr.b) {
bg = ptr.b;
} else if (this.search.flag) {
p.update({
qsearchflag: this.search.flag,
- qsearchflagnot: Number(this.convertFlag(this.search.flag, this.search.not))
+ qsearchflagnot: Number(this.search.not)
});
} else {
p.set('qsearch', $F('qsearch_input'));
$('ctx_flag').childElements().each(function(c) {
[ c ].invoke(flags.include(c.retrieve('flag')) ? 'show' : 'hide');
});
+ } else {
+ $('ctx_flag').childElements().invoke('show');
}
}.bindAsEventListener(this));
case 'ctx_folder_seen':
case 'ctx_folder_unseen':
- this.flagAll('\\seen', id == 'ctx_folder_seen', e.findElement('LI').retrieve('mbox'));
+ DimpCore.doAction('flagAll', {
+ add: Number(id == 'ctx_folder_seen'),
+ flags: Object.toJSON([ '\\seen' ]),
+ mbox: e.findElement('LI').retrieve('mbox')
+ });
break;
case 'ctx_folder_poll':
this.go('folder:' + DIMP.conf.fsearchid);
} else if (menu.endsWith('_setflag') || menu.endsWith('_unsetflag')) {
flag = elt.retrieve('flag');
- this.flag(flag, this.convertFlag(flag, menu.endsWith('_setflag')));
+ this.flag(flag, menu.endsWith('_setflag'));
} else if (menu.endsWith('_flag') || menu.endsWith('_flagnot')) {
this.search = {
flag: elt.retrieve('flag'),
a.store('filter', filter);
},
- contextAddFlag: function(flag, f)
+ contextAddFlag: function(flag, f, id)
{
var a = new Element('A'),
style = {};
- if (f.p) {
+ if (f.u) {
style.backgroundColor = f.b.escapeHTML();
}
- $('ctx_flag').insert(
+ $(id).insert(
a.insert(
- new Element('SPAN', { className: 'iconImg' }).addClassName(f.c.escapeHTML()).setStyle(style)
+ new Element('SPAN', { className: 'iconImg' }).addClassName(f.i ? f.i.escapeHTML() : f.c.escapeHTML()).setStyle(style)
).insert(
f.l.escapeHTML()
)
pp_uid = this._getPPId(data.imapuid, data.view);
if (this.ppfifo.indexOf(pp_uid) != -1) {
- // There is a chance that the message may have been marked
- // as unseen since first being viewed. If so, we need to
- // explicitly flag as seen here. TODO?
- if (!this.hasFlag('\\seen', data)) {
- this.flag('\\seen', true);
- }
return this._loadPreviewCallback(this.ppcache[pp_uid]);
}
}
_loadPreviewCallback: function(resp)
{
- var bg, ppuid, row, search, tmp,
+ var bg, ppuid, tmp, vs,
pm = $('previewMsg'),
r = resp.response.preview,
t = $('msgHeadersContent').down('THEAD');
bg = (this.pp &&
(this.pp.imapuid != r.uid || this.pp.view != r.mailbox));
- if (!r.error) {
- search = this.viewport.getSelection().search({ imapuid: { equal: [ r.uid ] }, view: { equal: [ r.mailbox ] } });
- if (search.size()) {
- row = search.get('dataob').first();
- this.updateSeenUID(row, 1);
- }
- }
-
if (r.error || this.viewport.getSelected().size() != 1) {
if (!bg) {
if (r.error) {
return;
}
+ vs = this.viewport.getSelection();
+
// Store in cache.
ppuid = this._getPPId(r.uid, r.mailbox);
this._expirePPCache([ ppuid ]);
}
// Toggle resume link
- [ $('msg_resume_draft').up() ].invoke(this.viewport.getSelection().get('dataob').first().draft ? 'show' : 'hide');
+ [ $('msg_resume_draft').up() ].invoke(vs.get('dataob').first().draft ? 'show' : 'hide');
$('messageBody').update(r.msgtext);
this.loadingImg('msg', false);
eval(r.js.join(';'));
}
- this.setHash('msg:' + row.view + ':' + row.imapuid);
+ this.setHash('msg:' + r.mailbox + ':' + r.uid);
},
_stripAttachmentCallback: function(r)
return uid + '|' + mailbox;
},
- // Labeling functions
- updateSeenUID: function(r, setflag)
- {
- var isunseen = !this.hasFlag('\\seen', r),
- sel, unseen;
-
- if ((setflag && !isunseen) || (!setflag && isunseen)) {
- return false;
- }
-
- sel = this.viewport.createSelection('dataob', r);
- unseen = this.getUnseenCount(r.view);
-
- unseen += setflag ? -1 : 1;
- this.updateFlag(sel, '\\seen', setflag);
-
- this.updateUnseenStatus(r.view, unseen);
- },
-
// mbox = (string)
getUnseenCount: function(mbox)
{
}
},
- _flagAllCallback: function(r)
+ flagCallback: function(r)
{
- if (r.response &&
- r.response.mbox == this.folder) {
- r.response.flags.each(function(f) {
- this.updateFlag(this.viewport.createSelectionBuffer(), f, r.response.set);
+ if (!r.flag ||
+ r.flag.mbox != this.folder) {
+ return;
+ }
+
+ var f = r.flag,
+ sb = f.uids
+ ? this.viewport.createSelection('uid', DimpCore.parseRangeString(f.uids)[f.mbox])
+ : this.viewport.createSelectionBuffer();
+
+ if (f.add) {
+ f.add.each(function(f) {
+ this.updateFlag(sb, f, true);
+ }, this);
+ }
+
+ if (f.remove) {
+ f.remove.each(function(f) {
+ this.updateFlag(sb, f, false);
}, this);
}
},
deleteMsg: function(opts)
{
opts = opts || {};
- var vs = this._getFlagSelection(opts);
-
- // Make sure that any given row is not deleted more than once. Need to
- // explicitly mark here because message may already be flagged deleted
- // when we load page (i.e. switching to using trash folder).
- vs = vs.search({ isdel: { notequal: [ true ] } });
- if (!vs.size()) {
- return;
- }
- vs.set({ isdel: true });
-
- opts.vs = vs;
+ opts.vs = this._getFlagSelection(opts);
this._doMsgAction('deleteMessages', opts, {});
- this.updateFlag(vs, '\\deleted', true);
+ this.updateFlag(opts.vs, '\\deleted', true);
},
// flag = (string) IMAP flag name
- // set = (boolean) True to set flag
- // opts = (Object) 'mailbox', 'noserver', 'uid'
- flag: function(flag, set, opts)
+ // add = (boolean) True to add flag
+ // opts = (Object) 'mailbox', 'uid'
+ flag: function(flag, add, opts)
{
- opts = opts || {};
- var flags = [ (set ? '' : '-') + flag ],
- vs = this._getFlagSelection(opts);
+ var vs = this._getFlagSelection(opts || {});
if (!vs.size()) {
return;
}
- switch (flag) {
- case '\\answered':
- if (set) {
- this.updateFlag(vs, '\\flagged', false);
- flags.push('-\\flagged');
- }
- break;
-
- case '\\deleted':
- vs.set({ isdel: false });
- break;
+ this.updateFlag(vs, flag, add);
- case '\\seen':
- vs.get('dataob').each(function(s) {
- this.updateSeenUID(s, set);
- }, this);
- break;
- }
-
- this.updateFlag(vs, flag, set);
- if (!opts.noserver) {
- DimpCore.doAction('flagMessages', this.viewport.addRequestParams({ flags: Object.toJSON(flags), view: this.folder }), { uids: vs });
- }
- },
-
- // type = (string) 'seen' or 'unseen'
- // mbox = (string) The mailbox to flag
- flagAll: function(type, set, mbox)
- {
- DimpCore.doAction('flagAll', { flags: Object.toJSON([ type ]), set: Number(set), mbox: mbox }, { callback: this._flagAllCallback.bind(this) });
+ DimpCore.doAction('flagMessages', this.viewport.addRequestParams({
+ add: Number(add),
+ flags: Object.toJSON([ flag ]),
+ view: this.folder
+ }), {
+ uids: vs
+ });
},
hasFlag: function(f, r)
{
- return this.convertFlag(f, r.flag ? r.flag.include(f) : false);
- },
-
- convertFlag: function(f, set)
- {
- /* For some flags, we need to do an inverse match (e.g. knowing a
- * message is SEEN is not as important as knowing the message lacks
- * the SEEN FLAG). This function will determine if, for a given flag,
- * the inverse action should be taken on it. */
- return DIMP.conf.flags[f].n ? !set : set;
+ return (r.flag ? r.flag.include(f) : false);
},
updateFlag: function(vs, flag, add)
{
var s = {};
- add = this.convertFlag(flag, add);
vs.get('dataob').each(function(ob) {
this._updateFlag(ob, flag, add);
});
DM.addSubMenu('ctx_qsearchopts_by', 'ctx_qsearchby');
DM.addSubMenu('ctx_qsearchopts_filter', 'ctx_filter');
- DM.addSubMenu('ctx_qsearchopts_flag', 'ctx_flag');
- DM.addSubMenu('ctx_qsearchopts_flagnot', 'ctx_flag');
+ DM.addSubMenu('ctx_qsearchopts_flag', 'ctx_flag_search');
+ DM.addSubMenu('ctx_qsearchopts_flagnot', 'ctx_flag_search');
/* Create flag entries. */
DIMP.conf.filters_o.each(function(f) {
/* Create flag entries. */
DIMP.conf.flags_o.each(function(f) {
if (DIMP.conf.flags[f].s) {
- this.contextAddFlag(f, DIMP.conf.flags[f]);
+ this.contextAddFlag(f, DIMP.conf.flags[f], 'ctx_flag_search');
+ }
+ if (DIMP.conf.flags[f].a) {
+ this.contextAddFlag(f, DIMP.conf.flags[f], 'ctx_flag');
}
}, this);
if (DimpBase.viewport) {
DimpBase.viewport.parseJSONResponse(r);
}
+ DimpBase.flagCallback(r);
DimpBase.pollCallback(r);
};
reloadMessage: function(params)
{
- if (typeof DimpFullmessage != 'undefined') {
+ if (typeof DimpMessage != 'undefined') {
window.location = this.addURLParam(document.location.href, params);
} else {
DimpBase.loadPreview(null, params);
+++ /dev/null
-/**
- * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- */
-
-var DimpFullmessage = {
-
- // Variables defaulting to empty/false: mailbox, uid
- quickreply: function(type)
- {
- var func, ob = {};
- ob[this.mailbox] = [ this.uid ];
-
- switch (type) {
- case 'reply':
- case 'reply_all':
- case 'reply_auto':
- case 'reply_list':
- $('compose').show();
- $('redirect').hide();
- func = 'getReplyData';
- break;
-
- case 'forward_auto':
- case 'forward_attach':
- case 'forward_body':
- case 'forward_both':
- $('compose').show();
- $('redirect').hide();
- func = 'getForwardData';
- break;
-
- case 'forward_redirect':
- $('compose').hide();
- $('redirect').show();
- func = 'getRedirectData';
- break;
- }
-
- $('msgData').hide();
- $('qreply').show();
-
- DimpCore.doAction(func,
- { imp_compose: $F('composeCache'),
- type: type },
- { uids: ob,
- callback: this.msgTextCallback.bind(this) });
- },
-
- msgTextCallback: function(result)
- {
- if (!result.response) {
- return;
- }
-
- var i, id,
- r = result.response;
-
- if (r.imp_compose) {
- $('composeCache').setValue(r.imp_compose);
- }
-
-
- if (r.type != 'forward_redirect') {
- if (!r.opts) {
- r.opts = {};
- }
- r.opts.noupdate = true;
- r.opts.show_editor = (r.format == 'html');
-
- id = (r.identity === null) ? $F('identity') : r.identity;
- i = IMP_Compose_Base.getIdentity(id, r.opts.show_editor);
-
- $('identity', 'last_identity').invoke('setValue', id);
-
- DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header, r.opts);
- }
- },
-
- /* Click handlers. */
- clickHandler: function(parentfunc, e)
- {
- if (e.isRightClick()) {
- return;
- }
-
- var elt = orig = e.element(), id;
-
- while (Object.isElement(elt)) {
- id = elt.readAttribute('id');
-
- switch (id) {
- case 'windowclose':
- window.close();
- e.stop();
- return;
-
- case 'forward_link':
- case 'reply_link':
- this.quickreply(id == 'reply_link' ? 'reply_auto' : 'forward_auto');
- e.stop();
- return;
-
- case 'button_deleted':
- case 'button_ham':
- case 'button_spam':
- if (DimpCore.base) {
- DimpCore.base.focus();
- if (id == 'button_deleted') {
- DimpCore.base.DimpBase.deleteMsg({ uid: this.uid, mailbox: this.mailbox });
- } else {
- DimpCore.base.DimpBase.reportSpam(id == 'button_spam', { uid: this.uid, mailbox: this.mailbox });
- }
- window.close();
- }
- e.stop();
- return;
-
- case 'msgloglist_toggle':
- case 'partlist_toggle':
- tmp = (id == 'partlist_toggle') ? 'partlist' : 'msgloglist';
- $(tmp + '_col', tmp + '_exp').invoke('toggle');
- Effect.toggle(tmp, 'blind', {
- afterFinish: function() {
- this.resizeWindow();
- $('msgData').down('DIV.messageBody').setStyle({ overflowY: 'auto' })
- }.bind(this),
- beforeSetup: function() {
- $('msgData').down('DIV.messageBody').setStyle({ overflowY: 'hidden' })
- },
- duration: 0.2,
- queue: {
- position: 'end',
- scope: tmp,
- limit: 2
- }
- });
- break;
-
- case 'msg_view_source':
- DimpCore.popupWindow(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { uid: this.uid, mailbox: this.mailbox, actionID: 'view_source', id: 0 }, true), this.uid + '|' + this.mailbox);
- break;
-
- case 'qreply':
- if (orig.match('DIV.headercloseimg IMG')) {
- DimpCompose.confirmCancel();
- }
- break;
-
- default:
- if (elt.hasClassName('printAtc')) {
- DimpCore.popupWindow(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { uid: this.uid, mailbox: this.mailbox, actionID: 'print_attach', id: elt.readAttribute('mimeid') }, true), this.uid + '|' + this.mailbox + '|print', IMP.printWindow);
- e.stop();
- return;
- } else if (elt.hasClassName('stripAtc')) {
- DimpCore.reloadMessage({
- actionID: 'strip_attachment',
- mailbox: this.mailbox,
- id: elt.readAttribute('mimeid'),
- uid: this.uid
- });
- e.stop();
- return;
- }
- break;
- }
-
- elt = elt.up();
- }
-
- parentfunc(e);
- },
-
- contextOnClick: function(parentfunc, e)
- {
- var id = e.memo.elt.readAttribute('id');
-
- switch (id) {
- case 'ctx_reply_reply':
- case 'ctx_reply_reply_all':
- case 'ctx_reply_reply_list':
- this.quickreply(id.substring(10));
- break;
-
- case 'ctx_forward_attach':
- case 'ctx_forward_body':
- case 'ctx_forward_both':
- case 'ctx_forward_redirect':
- this.quickreply(id.substring(4));
- break;
-
- default:
- parentfunc(e);
- break;
- }
- },
-
- resizeWindow: function()
- {
- var mb = $('msgData').down('DIV.messageBody');
-
- mb.setStyle({ height: (document.viewport.getHeight() - mb.cumulativeOffset()[1] - parseInt(mb.getStyle('paddingTop'), 10) - parseInt(mb.getStyle('paddingBottom'), 10)) + 'px' });
- },
-
- onDomLoad: function()
- {
- DimpCore.growler_log = false;
- DimpCore.init();
-
- if (DIMP.conf.disable_compose) {
- tmp = $('reply_link', 'forward_link').compact().invoke('up', 'SPAN').concat([ $('ctx_contacts_new') ]).compact().invoke('remove');
- } else {
- DimpCore.addPopdown('reply_link', 'replypopdown');
- DimpCore.addPopdown('forward_link', 'forwardpopdown');
- }
-
- /* Set up address linking. */
- [ 'from', 'to', 'cc', 'bcc', 'replyTo' ].each(function(a) {
- if (this[a]) {
- var elt = $('msgHeader' + a.charAt(0).toUpperCase() + a.substring(1)).down('TD', 1);
- elt.replace(DimpCore.buildAddressLinks(this[a], elt.clone(false)));
- }
- }, this);
-
- /* Add message information. */
- if (this.log) {
- $('msgLogInfo').show();
- DimpCore.updateMsgLog(this.log);
- }
-
- if (this.strip && DimpCore.base) {
- DimpCore.base.DimpBase.poll();
- }
-
- $('dimpLoading').hide();
- $('pageContainer').show();
-
- this.resizeWindow();
- }
-
-};
-
-/* ContextSensitive functions. */
-DimpCore.contextOnClick = DimpCore.contextOnClick.wrap(DimpFullmessage.contextOnClick.bind(DimpFullmessage));
-
-/* Click handler. */
-DimpCore.clickHandler = DimpCore.clickHandler.wrap(DimpFullmessage.clickHandler.bind(DimpFullmessage));
-
-/* Attach event handlers. */
-document.observe('dom:loaded', DimpFullmessage.onDomLoad.bind(DimpFullmessage));
-Event.observe(window, 'resize', DimpFullmessage.resizeWindow.bind(DimpFullmessage));
--- /dev/null
+/**
+ * Copyright 2005-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ */
+
+var DimpMessage = {
+
+ // Variables defaulting to empty/false: mailbox, uid
+ quickreply: function(type)
+ {
+ var func, ob = {};
+ ob[this.mailbox] = [ this.uid ];
+
+ switch (type) {
+ case 'reply':
+ case 'reply_all':
+ case 'reply_auto':
+ case 'reply_list':
+ $('compose').show();
+ $('redirect').hide();
+ func = 'getReplyData';
+ break;
+
+ case 'forward_auto':
+ case 'forward_attach':
+ case 'forward_body':
+ case 'forward_both':
+ $('compose').show();
+ $('redirect').hide();
+ func = 'getForwardData';
+ break;
+
+ case 'forward_redirect':
+ $('compose').hide();
+ $('redirect').show();
+ func = 'getRedirectData';
+ break;
+ }
+
+ $('msgData').hide();
+ $('qreply').show();
+
+ DimpCore.doAction(func,
+ { imp_compose: $F('composeCache'),
+ type: type },
+ { uids: ob,
+ callback: this.msgTextCallback.bind(this) });
+ },
+
+ msgTextCallback: function(result)
+ {
+ if (!result.response) {
+ return;
+ }
+
+ var i, id,
+ r = result.response;
+
+ if (r.imp_compose) {
+ $('composeCache').setValue(r.imp_compose);
+ }
+
+
+ if (r.type != 'forward_redirect') {
+ if (!r.opts) {
+ r.opts = {};
+ }
+ r.opts.noupdate = true;
+ r.opts.show_editor = (r.format == 'html');
+
+ id = (r.identity === null) ? $F('identity') : r.identity;
+ i = IMP_Compose_Base.getIdentity(id, r.opts.show_editor);
+
+ $('identity', 'last_identity').invoke('setValue', id);
+
+ DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header, r.opts);
+ }
+ },
+
+ /* Click handlers. */
+ clickHandler: function(parentfunc, e)
+ {
+ if (e.isRightClick()) {
+ return;
+ }
+
+ var elt = orig = e.element(), id;
+
+ while (Object.isElement(elt)) {
+ id = elt.readAttribute('id');
+
+ switch (id) {
+ case 'windowclose':
+ window.close();
+ e.stop();
+ return;
+
+ case 'forward_link':
+ case 'reply_link':
+ this.quickreply(id == 'reply_link' ? 'reply_auto' : 'forward_auto');
+ e.stop();
+ return;
+
+ case 'button_deleted':
+ case 'button_ham':
+ case 'button_spam':
+ if (DimpCore.base) {
+ DimpCore.base.focus();
+ if (id == 'button_deleted') {
+ DimpCore.base.DimpBase.deleteMsg({ uid: this.uid, mailbox: this.mailbox });
+ } else {
+ DimpCore.base.DimpBase.reportSpam(id == 'button_spam', { uid: this.uid, mailbox: this.mailbox });
+ }
+ window.close();
+ }
+ e.stop();
+ return;
+
+ case 'msgloglist_toggle':
+ case 'partlist_toggle':
+ tmp = (id == 'partlist_toggle') ? 'partlist' : 'msgloglist';
+ $(tmp + '_col', tmp + '_exp').invoke('toggle');
+ Effect.toggle(tmp, 'blind', {
+ afterFinish: function() {
+ this.resizeWindow();
+ $('msgData').down('DIV.messageBody').setStyle({ overflowY: 'auto' })
+ }.bind(this),
+ beforeSetup: function() {
+ $('msgData').down('DIV.messageBody').setStyle({ overflowY: 'hidden' })
+ },
+ duration: 0.2,
+ queue: {
+ position: 'end',
+ scope: tmp,
+ limit: 2
+ }
+ });
+ break;
+
+ case 'msg_view_source':
+ DimpCore.popupWindow(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { uid: this.uid, mailbox: this.mailbox, actionID: 'view_source', id: 0 }, true), this.uid + '|' + this.mailbox);
+ break;
+
+ case 'qreply':
+ if (orig.match('DIV.headercloseimg IMG')) {
+ DimpCompose.confirmCancel();
+ }
+ break;
+
+ default:
+ if (elt.hasClassName('printAtc')) {
+ DimpCore.popupWindow(DimpCore.addURLParam(DIMP.conf.URI_VIEW, { uid: this.uid, mailbox: this.mailbox, actionID: 'print_attach', id: elt.readAttribute('mimeid') }, true), this.uid + '|' + this.mailbox + '|print', IMP.printWindow);
+ e.stop();
+ return;
+ } else if (elt.hasClassName('stripAtc')) {
+ DimpCore.reloadMessage({
+ actionID: 'strip_attachment',
+ mailbox: this.mailbox,
+ id: elt.readAttribute('mimeid'),
+ uid: this.uid
+ });
+ e.stop();
+ return;
+ }
+ break;
+ }
+
+ elt = elt.up();
+ }
+
+ parentfunc(e);
+ },
+
+ contextOnClick: function(parentfunc, e)
+ {
+ var id = e.memo.elt.readAttribute('id');
+
+ switch (id) {
+ case 'ctx_reply_reply':
+ case 'ctx_reply_reply_all':
+ case 'ctx_reply_reply_list':
+ this.quickreply(id.substring(10));
+ break;
+
+ case 'ctx_forward_attach':
+ case 'ctx_forward_body':
+ case 'ctx_forward_both':
+ case 'ctx_forward_redirect':
+ this.quickreply(id.substring(4));
+ break;
+
+ default:
+ parentfunc(e);
+ break;
+ }
+ },
+
+ resizeWindow: function()
+ {
+ var mb = $('msgData').down('DIV.messageBody');
+
+ mb.setStyle({ height: (document.viewport.getHeight() - mb.cumulativeOffset()[1] - parseInt(mb.getStyle('paddingTop'), 10) - parseInt(mb.getStyle('paddingBottom'), 10)) + 'px' });
+ },
+
+ onDomLoad: function()
+ {
+ DimpCore.growler_log = false;
+ DimpCore.init();
+
+ if (DIMP.conf.disable_compose) {
+ tmp = $('reply_link', 'forward_link').compact().invoke('up', 'SPAN').concat([ $('ctx_contacts_new') ]).compact().invoke('remove');
+ } else {
+ DimpCore.addPopdown('reply_link', 'replypopdown');
+ DimpCore.addPopdown('forward_link', 'forwardpopdown');
+ }
+
+ /* Set up address linking. */
+ [ 'from', 'to', 'cc', 'bcc', 'replyTo' ].each(function(a) {
+ if (this[a]) {
+ var elt = $('msgHeader' + a.charAt(0).toUpperCase() + a.substring(1)).down('TD', 1);
+ elt.replace(DimpCore.buildAddressLinks(this[a], elt.clone(false)));
+ }
+ }, this);
+
+ /* Add message information. */
+ if (this.log) {
+ $('msgLogInfo').show();
+ DimpCore.updateMsgLog(this.log);
+ }
+
+ if (DimpCore.base) {
+ if (this.strip) {
+ DimpCore.base.DimpBase.poll();
+ } else if (this.poll) {
+ DimpCore.base.DimpBase.pollCallback({ poll: this.poll });
+ }
+
+ if (this.flag) {
+ DimpCore.base.DimpBase.flagCallback({ flag: this.flag });
+ }
+ }
+
+ $('dimpLoading').hide();
+ $('pageContainer').show();
+
+ this.resizeWindow();
+ }
+
+};
+
+/* ContextSensitive functions. */
+DimpCore.contextOnClick = DimpCore.contextOnClick.wrap(DimpMessage.contextOnClick.bind(DimpMessage));
+
+/* Click handler. */
+DimpCore.clickHandler = DimpCore.clickHandler.wrap(DimpMessage.clickHandler.bind(DimpMessage));
+
+/* Attach event handlers. */
+document.observe('dom:loaded', DimpMessage.onDomLoad.bind(DimpMessage));
+Event.observe(window, 'resize', DimpMessage.resizeWindow.bind(DimpMessage));
*
* Variables used:
* <pre>
- * 'flags' - (string) The flags to set (JSON serialized array).
+ * 'add' - (integer) Add the flags?
+ * 'flags' - (string) The IMAP flags to add/remove (JSON serialized
+ * array).
* 'mbox' - (string) The full malbox name.
- * 'set' - (integer) Set the flags?
* </pre>
*
* @return mixed False on failure, or an object with the following
* entries:
* <pre>
- * 'flags' - (array) The list of flags that were set.
- * 'mbox' - (string) The full mailbox name.
+ * 'flag' - (object) See flagEntry().
* 'poll' - (array) Mailbox names as the keys, number of unseen messages
* as the values.
- * 'set' - (integer) 1 if the flag was set. Unset otherwise.
* </pre>
*/
public function flagAll()
{
$flags = Horde_Serialize::unserialize($this->_vars->flags, Horde_Serialize::JSON);
- if (!$this->_vars->mbox || empty($flags)) {
+ if (!$this->_vars->mbox ||
+ empty($flags) ||
+ !$GLOBALS['injector']->getInstance('IMP_Message')->flagAllInMailbox($flags, array($this->_vars->mbox), $this->_vars->add)) {
return false;
}
- $result = $GLOBALS['injector']->getInstance('IMP_Message')->flagAllInMailbox($flags, array($this->_vars->mbox), $this->_vars->set);
+ $result = new stdClass;
- if ($result) {
- $result = new stdClass;
- $result->flags = $flags;
- $result->mbox = $this->_vars->mbox;
- if ($this->_vars->set) {
- $result->set = 1;
- }
+ /* Get list of flags that were also affected by this flag
+ * change. */
+ $result->flag = $this->flagEntry($flags, $this->_vars->add, $this->_vars->mbox);
- $poll = $this->_getPollInformation($this->_vars->mbox);
- if (!empty($poll)) {
- $result->poll = array($this->_vars->mbox => $poll[$this->_vars->mbox]);
- }
+ if ($poll = $this->pollEntry($this->_vars->mbox)) {
+ $result->poll = $poll;
}
return $result;
$changed = false;
$result = new stdClass;
- $result->poll = array();
-
- foreach ($GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create()->statusMultiple($GLOBALS['injector']->getInstance('IMP_Imap_Tree')->getPollList(), Horde_Imap_Client::STATUS_UNSEEN) as $key => $val) {
- $result->poll[$key] = intval($val['unseen']);
- }
+ $result->poll = $this->pollEntry();
if ($this->_vars->view &&
($changed = $this->_changed())) {
/* Update poll information for destination folder if necessary.
* Poll information for current folder will be added by
* _generateDeleteResult() call above. */
- if ($poll = $this->_getPollInformation($this->_vars->mboxto)) {
+ if ($poll = $this->pollEntry($this->_vars->mboxto)) {
$result->poll = array_merge(isset($result->poll) ? $result->poll : array(), $poll);
}
} else {
}
if ($result = $GLOBALS['injector']->getInstance('IMP_Message')->copy($this->_vars->mboxto, 'copy', $indices)) {
- if ($poll = $this->_getPollInformation($this->_vars->mboxto)) {
+ if ($poll = $this->pollEntry($this->_vars->mboxto)) {
$result->poll = array_merge(isset($result->poll) ? $result->poll : array(), $poll);
}
} else {
* See the list of variables needed for _changed() and
* _checkUidvalidity(). Additional variables used:
* <pre>
+ * 'add' - (integer) Set the flag?
* 'flags' - (string) The flags to set (JSON serialized array).
* 'uid' - (string) Indices of the messages to flag (IMAP sequence
* string).
* @return mixed False on failure, or an object with the following
* entries:
* <pre>
+ * 'flag' - (object) See flagEntry().
+ * 'poll' - (array) See pollEntry().
* 'ViewPort' - (object) See _viewPortData().
* </pre>
*/
}
$flags = Horde_Serialize::unserialize($this->_vars->flags, Horde_Serialize::JSON);
- $set = $notset = array();
- foreach ($flags as $val) {
- if ($val[0] == '-') {
- $notset[] = substr($val, 1);
- } else {
- $set[] = $val;
- }
+ if (!$GLOBALS['injector']->getInstance('IMP_Message')->flag($flags, $indices, $this->_vars->add)) {
+ return $this->_checkUidvalidity();
}
- if (!empty($set)) {
- $result = $GLOBALS['injector']->getInstance('IMP_Message')->flag($set, $indices, true);
- }
+ $result = new stdClass;
+ list($mbox, $uids) = $indices->getSingle(true);
+ $result->flag = $this->flagEntry($flags, $this->_vars->add, $mbox, $uids);
- if (!empty($notset)) {
- $result = $GLOBALS['injector']->getInstance('IMP_Message')->flag($notset, $indices, false);
+ if (in_array('\\seen', $flags) && ($poll = $this->pollEntry($mbox))) {
+ $result->poll = $poll;
}
- if ($result) {
- $result = new stdClass;
- if ($change) {
- $result->ViewPort = $this->_viewPortData(true);
- } else {
- $result->ViewPort = new stdClass;
- $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_MailboxList')->create($this->_vars->view)->getCacheID($this->_vars->view);
- $result->ViewPort->view = $this->_vars->view;
- }
- return $result;
+ if ($change) {
+ $result->ViewPort = $this->_viewPortData(true);
+ } else {
+ $result->ViewPort = new stdClass;
+ $result->ViewPort->updatecacheid = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_MailboxList')->create($this->_vars->view)->getCacheID($this->_vars->view);
+ $result->ViewPort->view = $this->_vars->view;
}
- return $this->_checkUidvalidity();
+ return $result;
}
/**
* @return mixed False on failure, or an object with the following
* entries:
* <pre>
+ * 'flag' - (object) See flagEntry().
+ * 'poll' - (array) Mailbox names as the keys, number of unseen messages
+ * as the values.
* 'preview' - (object) Return from IMP_View_ShowMessage::showMessage().
* 'ViewPort' - (object) See _viewPortData(). (Only returns updatecacheid
* entry - don't do mailbox poll here).
$result->ViewPort->view = $this->_vars->view;
}
}
+
+ if ($poll = $this->pollEntry($this->_vars->view)) {
+ $result->poll = $poll;
+ }
+
+ /* Add changed flag information. */
+ $result->flag = $this->flagEntry(array('\\seen'), true, $mbox, $idx);
} catch (Horde_Imap_Client_Exception $e) {
$result->preview->error = $e->getMessage();
$result->preview->errortype = 'horde.error';
* 'action' - (string) The AJAX action string
* 'draft_delete' - (integer) TODO
* 'encryptjs' - (array) Javascript to run after encryption failure.
+ * 'flag' - (object) See flagEntry().
* 'identity' - (integer) If set, this is the identity that is tied to
* the current recipient address.
* 'log' - (array) TODO
* 'mailbox' - (array) TODO
- * 'reply_folder' - (string) TODO
- * 'reply_type' - (string) TODO
+ * 'mbox' - (string) Mailbox of original message.
* 'success' - (integer) 1 on success, 0 on failure.
- * 'uid' - (integer) TODO
+ * 'uid' - (integer) IMAP UID of original message.
* </pre>
*/
public function sendMessage()
$headers['replyto'] = $identity->getValue('replyto_addr');
- $result->uid = $imp_compose->getMetadata('uid');
-
- if ($reply_type = $imp_compose->getMetadata('reply_type')) {
- $result->reply_folder = $imp_compose->getMetadata('mailbox');
- $result->reply_type = $reply_type;
- }
-
/* Use IMP_Tree to determine whether the sent mail folder was
* created. */
$imptree = $GLOBALS['injector']->getInstance('IMP_Imap_Tree');
}
}
+ $result->mbox = $imp_compose->getMetadata('mailbox');
+ $result->uid = $imp_compose->getMetadata('uid');
+
+ switch ($imp_compose->getMetadata('reply_type')) {
+ case 'forward':
+ $result->flag = $this->flagEntry(array('$forwarded'), true, $result->mbox, $result->uid);
+ break;
+
+ case 'reply':
+ case 'reply_all':
+ case 'reply_list':
+ $result->flag = $this->flagEntry(array('\\answered'), true, $result->mbox, $result->uid);
+ break;
+ }
+
$imp_compose->destroy('send');
$result->mailbox = $this->_getMailboxResponse($imptree);
}
/**
+ * Generate flag updated entry.
+ *
+ * @param array $flags List of flags that have changed.
+ * @param boolean $add Were the flags added?
+ * @param string $mbox Mailbox where flags changed.
+ * @param string $uids IMAP UIDs of the changed flags.
+ *
+ * @return stdClass Object with these properties:
+ * <pre>
+ * 'add' - (array) The list of flags that were added.
+ * 'mbox' - (string) The full mailbox name.
+ * 'remove' - (array) The list of flags that were removed.
+ * 'uids' - (string) Indices of the messages that have changed (IMAP
+ * sequence string); if empty, all messages in mailbox have
+ * changed.
+ * </pre>
+ */
+ static public function flagEntry($flags, $add, $mbox, $uids = null)
+ {
+ $changed = $GLOBALS['injector']->getInstance('IMP_Flags')->changed($flags, $add);
+
+ $result = new stdClass;
+ if (!empty($changed['add'])) {
+ $result->add = array_map('strval', $changed['add']);
+ }
+ $result->mbox = $mbox;
+ if (!empty($changed['remove'])) {
+ $result->remove = array_map('strval', $changed['remove']);
+ }
+ if (!is_null($uids)) {
+ $result->uids = strval(new IMP_Indices($mbox, $uids));
+ }
+
+ return $result;
+ }
+
+ /**
+ * Generate poll information for mailboxes.
+ *
+ * @param string $mbox The full mailbox name. If null, all polled
+ * mailboxes are returned.
+ *
+ * @return array Keys are mailbox names, values are the number of unseen
+ * messages.
+ */
+ static public function pollEntry($mbox = null)
+ {
+ $imaptree = $GLOBALS['injector']->getInstance('IMP_Imap_Tree');
+
+ if (is_null($mbox)) {
+ $result = array();
+ foreach ($GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create()->statusMultiple($imaptree->getPollList(), Horde_Imap_Client::STATUS_UNSEEN) as $key => $val) {
+ $result[$key] = intval($val['unseen']);
+ }
+ return $result;
+ }
+
+ return $imaptree[$mbox]->polled
+ ? array($mbox => $imaptree[$mbox]->poll_info->unseen)
+ : array();
+ }
+
+ /**
* Setup environment for dimp compose actions.
*
* Variables used:
$result->ViewPort->view = $this->_vars->view;
}
- $poll = $this->_getPollInformation($this->_vars->view);
- if (!empty($poll)) {
+ if ($poll = $this->pollEntry($this->_vars->view)) {
$result->poll = $poll;
}
}
/**
- * Generate poll information for a single mailbox.
- *
- * @param string $mbox The full mailbox name.
- *
- * @return array Key is the mailbox name, value is the number of unseen
- * messages.
- */
- protected function _getPollInformation($mbox)
- {
- $imaptree = $GLOBALS['injector']->getInstance('IMP_Imap_Tree');
-
- return $imaptree[$mbox]->polled
- ? array($mbox => $imaptree[$mbox]->poll_info->unseen)
- : array();
- }
-
- /**
* Generate quota information.
*
* @return array 'p': Quota percentage; 'm': Quota message
* @param string $mailbox If set, returns the list of flags filtered by
* what the mailbox allows.
*
- * @return array See IMP_Imap_Flags::getList() for the output. The
- * 'f' key will be set.
+ * @return array A list of IMP_Flag_Base objects.
*/
public function flagList($mailbox = null)
{
return array();
}
- $opts = array(
- 'fgcolor' => true,
+ return $GLOBALS['injector']->getInstance('IMP_Flags')->getList(array(
'imap' => true,
- );
-
- if (!is_null($mailbox)) {
- $opts['mailbox'] = $mailbox;
- }
-
- return $GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList($opts);
+ 'mailbox' => $mailbox
+ ));
}
}
'IMP_AuthImap' => 'IMP_Injector_Factory_AuthImap',
'IMP_Crypt_Pgp' => 'IMP_Injector_Factory_Pgp',
'IMP_Crypt_Smime' => 'IMP_Injector_Factory_Smime',
+ 'IMP_Flags' => 'IMP_Injector_Factory_Flags',
'IMP_Identity' => 'IMP_Injector_Factory_Identity',
'IMP_Imap_Tree' => 'IMP_Injector_Factory_Imaptree',
'IMP_Mail' => 'IMP_Injector_Factory_Mail',
--- /dev/null
+<?php
+/**
+ * This class provides the data structure for a message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+abstract class IMP_Flag_Base implements Serializable
+{
+ /* Default background color. */
+ const DEFAULT_BG = '#fff';
+
+ /**
+ * The abbreviation.
+ *
+ * @var string
+ */
+ protected $_abbreviation = '';
+
+ /**
+ * The background color.
+ *
+ * @var string
+ */
+ protected $_bgcolor = '';
+
+ /**
+ * Is this flag settable by the user?
+ *
+ * @var boolean
+ */
+ protected $_canset = false;
+
+ /**
+ * The CSS class.
+ *
+ * @var string
+ */
+ protected $_css = '';
+
+ /**
+ * The CSS class for the icon.
+ *
+ * @var string
+ */
+ protected $_cssIcon = '';
+
+ /**
+ * Unique ID.
+ *
+ * @var string
+ */
+ protected $_id = '';
+
+ /**
+ * Get object properties.
+ *
+ * @param string $name Available properties:
+ * <pre>
+ * 'abbreviation' - (string) The abbreviation to use in the mimp view.
+ * 'bgcolor' - (string) The background color.
+ * 'bgdefault' - (boolean) Is the backgroud color the default?
+ * 'canset' - (boolean) Can this flag be set by the user?
+ * 'css' - (string) The CSS class for the icon when the flag is set.
+ * 'cssicon' - (string) The CSS class for the icon.
+ * 'div' - (string) Return DIV HTML to output the icon for use in a
+ * mailbox row.
+ * 'fgcolor' - (string) The foreground (text) color.
+ * 'form_set' - (string) Form value to use when setting flag.
+ * 'form_unset' - (string) Form value to use when unsetting flag.
+ * 'id' - (string) Unique ID.
+ * 'label' - (string) The query label.
+ * </pre>
+ *
+ * @return mixed Property value.
+ */
+ public function __get($name)
+ {
+ switch ($name) {
+ case 'abbreviation':
+ return $this->_abbreviation;
+
+ case 'bgcolor':
+ return $this->_bgcolor
+ ? $this->_bgcolor
+ : self::DEFAULT_BG;
+
+ case 'bgdefault':
+ return ($this->bgcolor == self::DEFAULT_BG);
+
+ case 'canset':
+ return $this->_canset;
+
+ case 'css':
+ return $this->_css;
+
+ case 'cssicon':
+ return $this->_cssIcon
+ ? $this->_cssIcon
+ : $this->_css;
+
+ case 'div':
+ return $this->_css
+ ? '<div class="iconImg msgflags ' . $this->css . '" title="' . htmlspecialchars($this->label) . '"></div>'
+ : '';
+
+ case 'fgcolor':
+ return (Horde_Image::brightness($this->bgcolor) < 128)
+ ? '#f6f6f6'
+ : '#000';
+
+ case 'form_set':
+ return $this->id;
+
+ case 'form_unset':
+ return '0\\' . $this->id;
+
+ case 'id':
+ return $this->_id;
+
+ case 'label':
+ return $this->getLabel();
+ }
+ }
+
+ /**
+ * Set properties.
+ *
+ * @param string $name Available properties:
+ * <pre>
+ * 'bgcolor' - (string) The background color.
+ * </pre>
+ * @param string $value Property value.
+ */
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case 'bgcolor':
+ $this->_bgcolor = ($value == self::DEFAULT_BG)
+ ? ''
+ : $value;
+ break;
+ }
+ }
+
+ /**
+ * Given a list of flag objects, determines if this flag's status has
+ * changed.
+ *
+ * @param array $obs A list of IMP_Flag_Base objects.
+ * @param boolean $add True if these flags were added, false if they were
+ * removed.
+ *
+ * @return mixed Null if no change, true if flag is added, false if flag
+ * is removed.
+ */
+ public function changed($obs, $add)
+ {
+ return null;
+ }
+
+ /**
+ * Return the flag label.
+ *
+ * @param boolean $set Return label for setting the flag?
+ *
+ * @return string The label.
+ */
+ public function getLabel($set = true)
+ {
+ return $set
+ ? $this->_getLabel()
+ : sprintf(_("Not %s"), $this->_getLabel());
+ }
+
+ /**
+ * Determines if the flag exists given some input data.
+ *
+ * @param mixed $data The input data to check.
+ *
+ * @return boolean True if flag exists.
+ */
+ abstract public function match($data);
+
+ /**
+ * Return the flag label.
+ * Necessary evil as gettext strings can not be set directly to object
+ * properties.
+ *
+ * @return string The label.
+ */
+ abstract protected function _getLabel();
+
+ /* Magic methods. */
+
+ /**
+ * String representation of the object.
+ *
+ * @return string String representation (Flag ID).
+ */
+ public function __toString()
+ {
+ return $this->id;
+ }
+
+ /* Serializable methods. */
+
+ /**
+ */
+ public function serialize()
+ {
+ return $this->_bgcolor;
+ }
+
+ /**
+ */
+ public function unserialize($data)
+ {
+ $this->_bgcolor = $data;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides the data structure for a message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+abstract class IMP_Flag_Imap extends IMP_Flag_Base
+{
+ /**
+ * The IMAP flag string used on the server.
+ *
+ * @var string
+ */
+ protected $_imapflag;
+
+ /**
+ * @param string $name Additional properties:
+ * <pre>
+ * 'imapflag' - (string) The IMAP flag string.
+ * </pre>
+ */
+ public function __get($name)
+ {
+ switch ($name) {
+ case 'id':
+ case 'imapflag':
+ return $this->_imapflag;
+
+ default:
+ return parent::__get($name);
+ }
+ }
+
+ /**
+ * @param array $input List of IMAP flags.
+ */
+ public function match($data)
+ {
+ return in_array($this->imapflag, $data);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the answered flag (RFC 3501 [2.3.2]).
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Answered extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_bgcolor = '#cfc';
+
+ /**
+ */
+ protected $_css = 'flagAnswered';
+
+ /**
+ */
+ protected $_imapflag = '\\answered';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Answered");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the deleted flag (RFC 3501 [2.3.2]).
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Deleted extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_abbreviation = 'D';
+
+ /**
+ */
+ protected $_bgcolor = '#999';
+
+ /**
+ */
+ protected $_css = 'flagDeleted';
+
+ /**
+ */
+ protected $_imapflag = '\\deleted';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Deleted");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the draft flag (RFC 3501 [2.3.2]).
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Draft extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_abbreviation = 'd';
+
+ /**
+ */
+ protected $_bgcolor = '#ffd93d';
+
+ /**
+ */
+ protected $_css = 'flagDraft';
+
+ /**
+ */
+ protected $_imapflag = '\\draft';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Draft");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the flagged for followup flag (RFC 3501 [2.3.2]).
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Flagged extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_bgcolor = '#fcc';
+
+ /**
+ */
+ protected $_canset = true;
+
+ /**
+ */
+ protected $_css = 'flagFlagged';
+
+ /**
+ */
+ protected $_imapflag = '\\flagged';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Flagged for Followup");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the forwarded flag (RFC 5550 [5.9]).
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Forwarded extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_bgcolor = '#bfdfdf';
+
+ /**
+ */
+ protected $_css = 'flagForwarded';
+
+ /**
+ */
+ protected $_imapflag = '$forwarded';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Forwarded");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the seen flag (RFC 3501 [2.3.2]).
+ * Unseen display formatting is handled by the IMP_Flag_System_Unseen class.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_Imap_Seen extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_canset = true;
+
+ /**
+ */
+ protected $_cssIcon = 'flagSeen';
+
+ /**
+ */
+ protected $_imapflag = '\\seen';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Seen");
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides the data structure for an internal system flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+abstract class IMP_Flag_System extends IMP_Flag_Base
+{
+}
--- /dev/null
+<?php
+/**
+ * This class implements the attachment flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_Attachment extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_css = 'flagAttachmsg';
+
+ /**
+ */
+ protected $_id = 'attach';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Message has Attachments");
+ }
+
+ /**
+ * @param Horde_Mime_Headers $data Headers object for a message.
+ */
+ public function match($data)
+ {
+ if (!($ctype = $data->getValue('content-type', Horde_Mime_Headers::VALUE_BASE))) {
+ return false;
+ }
+
+ list($primary, $sub) = explode('/', $ctype, 2);
+ return (($primary == 'multipart') &&
+ !in_array($sub, array('alternative', 'encrypt', 'related', 'signed')));
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the encrypted message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_Encrypted extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_css = 'flagEncryptmsg';
+
+ /**
+ */
+ protected $_id = 'encrypted';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Message is Encrypted");
+ }
+
+ /**
+ * @param Horde_Mime_Headers $data Headers object for a message.
+ */
+ public function match($data)
+ {
+ $ctype = $data->getValue('content-type', Horde_Mime_Headers::VALUE_BASE);
+
+ return (($ctype == 'application/pkcs7-mime') ||
+ ($ctype == 'multipart/encrypted'));
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the high priority flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_HighPriority extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_abbreviation = '!';
+
+ /**
+ */
+ protected $_bgcolor = '#fcc';
+
+ /**
+ */
+ protected $_css = 'flagHighpriority';
+
+ /**
+ */
+ protected $_id = 'highp';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("High Priority");
+ }
+
+ /**
+ * @param Horde_Mime_Headers $data Headers object for a message.
+ */
+ public function match($data)
+ {
+ return ($GLOBALS['injector']->getInstance('IMP_Ui_Headers')->getPriority($data) == 'high');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the low priority flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_LowPriority extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_css = 'flagLowpriority';
+
+ /**
+ */
+ protected $_id = 'lowp';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Low Priority");
+ }
+
+ /**
+ * @param Horde_Mime_Headers $data Headers object for a message.
+ */
+ public function match($data)
+ {
+ return ($GLOBALS['injector']->getInstance('IMP_Ui_Headers')->getPriority($data) == 'low');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the personal message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_Personal extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_css = 'flagPersonal';
+
+ /**
+ */
+ protected $_id = 'personal';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Personal");
+ }
+
+ /**
+ * @param mixed $data Either an array of To addresses as returned by
+ * Horde_Mime_Address::getAddressesFromObject() or the
+ * identity that matched the address list.
+ */
+ public function match($data)
+ {
+ if (is_array($data)) {
+ $identity = $GLOBALS['injector']->getInstance('IMP_Identity');
+
+ foreach ($data as $val) {
+ if ($identity->hasAddress($val['inner'])) {
+ return true;
+ }
+ }
+ } else if (!is_null($data)) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements the signed message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_Signed extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_css = 'flagSignedmsg';
+
+ /**
+ */
+ protected $_id = 'signed';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Message is Signed");
+ }
+
+ /**
+ * @param Horde_Mime_Headers $data Headers object for a message.
+ */
+ public function match($data)
+ {
+ return ($data->getValue('content-type', Horde_Mime_Headers::VALUE_BASE) == 'multipart/signed');
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class implements formatting for unseen messages. Unseen occurs when
+ * the seen flag (RFC 3501 [2.3.2]) is NOT set; thus, it can not be handled
+ * in the seen flag object.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_System_Unseen extends IMP_Flag_System
+{
+ /**
+ */
+ protected $_abbreviation = 'U';
+
+ /**
+ */
+ protected $_bgcolor = '#eef';
+
+ /**
+ */
+ protected $_css = 'flagUnseen';
+
+ /**
+ */
+ protected $_id = 'unseen';
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return _("Unseen");
+ }
+
+ /**
+ */
+ public function changed($obs, $add)
+ {
+ foreach ($obs as $val) {
+ if ($val instanceof IMP_Flag_Imap_Seen) {
+ return !$add;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param array $data List of IMAP flags.
+ */
+ public function match($data)
+ {
+ return !in_array('\\seen', $data);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * This class provides the data structure for a user-defined message flag.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flag_User extends IMP_Flag_Imap
+{
+ /**
+ */
+ protected $_canset = true;
+
+ /**
+ */
+ protected $_css = 'flagUser';
+
+ /**
+ * The flag label.
+ *
+ * @var string
+ */
+ protected $_label;
+
+ /**
+ * Constructor.
+ *
+ * @param string $label The label.
+ * @param string $flag The IMAP flag.
+ * @param string $bgcolor The background color.
+ */
+ public function __construct($label, $flag = null, $bgcolor = null)
+ {
+ $this->label = $label;
+ $this->imapflag = is_null($flag)
+ ? $label
+ : $flag;
+ if (isset($bgcolor)) {
+ $this->bgcolor = $bgcolor;
+ }
+ }
+
+ /**
+ */
+ public function __set($name, $value)
+ {
+ switch ($name) {
+ case 'imapflag':
+ /* IMAP keywords must conform to RFC 3501 [9] (flag-keyword).
+ * Convert whitespace to underscore. */
+ $this->_imapflag = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create()->getUtils()->stripNonAtomChars(Horde_String::convertCharset(strtr($value, ' ', '_'), 'UTF-8', 'UTF7-IMAP'));
+ break;
+
+ case 'label':
+ $this->_label = $value;
+ break;
+
+ default:
+ parent::__set($name, $value);
+ break;
+ }
+ }
+
+ /**
+ */
+ protected function _getLabel()
+ {
+ return $this->_label;
+ }
+
+ /* Serializable methods. */
+
+ /**
+ */
+ public function serialize()
+ {
+ return json_encode(array(
+ parent::serialize(),
+ $this->_label,
+ $this->_imapflag
+ ));
+ }
+
+ /**
+ */
+ public function unserialize($data)
+ {
+ $data = json_decode($data, true);
+
+ parent::unserialize($data[0]);
+ $this->_label = $data[1];
+ $this->_imapflag = $data[2];
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The IMP_Flags class provides an interface to deal with display of
+ * flags/keywords/labels on messages.
+ *
+ * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @package IMP
+ */
+class IMP_Flags implements ArrayAccess, Serializable
+{
+ /**
+ * Has the object data changed?
+ *
+ * @var boolean
+ */
+ public $changed = false;
+
+ /**
+ * The list of internal flags.
+ *
+ * @var array
+ */
+ protected $_flags = array();
+
+ /**
+ * The list of user flags.
+ *
+ * @var array
+ */
+ protected $_userflags = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ /* Build list of default flags. */
+ foreach (array('Imap', 'System') as $type) {
+ $di = new DirectoryIterator(IMP_BASE . '/lib/Flag/' . $type);
+ foreach ($di as $val) {
+ if ($val->isFile()) {
+ $cname = 'IMP_Flag_' . $type . '_' . $val->getBasename('.php');
+ if (class_exists($cname)) {
+ $ob = new $cname();
+ $this->_flags[$ob->id] = $ob;
+ }
+ }
+ }
+ }
+
+ if ($f_list = $GLOBALS['prefs']->getValue('msgflags')) {
+ $f_list = @unserialize($f_list);
+ if (is_array($f_list)) {
+ foreach ($f_list as $val) {
+ $this->_userflags[$val->id] = $val;
+ }
+ }
+ }
+
+ $this->changed = true;
+ }
+
+ /**
+ * Save the flag list to the prefs backend.
+ */
+ protected function _save()
+ {
+ global $prefs;
+
+ if (!$prefs->isLocked('msgflags')) {
+ $prefs->setValue('msgflags', serialize($this->_userflags));
+ }
+
+ $this->changed = true;
+ }
+
+ /**
+ * Return the raw list of flags.
+ *
+ * @param array $opts Additional options:
+ * <pre>
+ * 'imap' - (boolean) If true, only return IMAP flags that can be set by
+ * the user.
+ * DEFAULT: false
+ * 'mailbox' - (string) A real (not virtual) IMAP mailbox. If set, will
+ * determine what flags are available in the mailbox.
+ * DEFAULT: '' (no mailbox check)
+ * </pre>
+ *
+ * @return array An array of IMP_Flag_Base elements.
+ */
+ public function getList(array $opts = array())
+ {
+ $ret = array_merge($this->_flags, $this->_userflags);
+
+ if (!empty($opts['imap'])) {
+ foreach ($ret as $key => $val) {
+ if (!($val instanceof IMP_Flag_Imap)) {
+ unset($ret[$key]);
+ }
+ }
+ }
+
+ if (!isset($opts['mailbox']) || !strlen($opts['mailbox'])) {
+ return array_values($ret);
+ }
+
+ /* Alter the list of flags for a mailbox depending on the return
+ * from the PERMANENTFLAGS IMAP response. */
+ try {
+ /* Make sure we are in R/W mailbox mode (SELECT). No flags are
+ * allowed in EXAMINE mode. */
+ $imp_imap = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create();
+ $imp_imap->openMailbox($opts['mailbox'], Horde_Imap_Client::OPEN_READWRITE);
+ $status = $imp_imap->status($opts['mailbox'], Horde_Imap_Client::STATUS_PERMFLAGS);
+ } catch (Horde_Imap_Client_Exception $e) {
+ return array_values($ret);
+ }
+
+ /* Limited flags allowed in mailbox. */
+ if (array_search('\\*', $status['permflags']) === false) {
+ foreach ($ret as $key => $val) {
+ if (($val instanceof IMP_Flag_Imap) &&
+ !in_array($val->imapflag, $status['permflags'])) {
+ unset($ret[$key]);
+ }
+ }
+ }
+
+ /* Get list of unknown flags. */
+ if ($GLOBALS['prefs']->getValue('show_all_flags')) {
+ /* Get list of IMAP flags. */
+ $imapflags = array();
+ foreach ($ret as $val) {
+ if ($val instanceof IMP_Flag_Imap) {
+ $imapflags[] = $val->imapflag;
+ }
+ }
+
+ foreach ($status['permflags'] as $val) {
+ if (($val != '\\*') && !in_array($val, $imapflags)) {
+ $ob = new IMP_Flag_User(Horde_String::convertCharset($val, 'UTF7-IMAP', 'UTF-8'), $val);
+ $ret[] = $ob;
+ }
+ }
+ }
+
+ return array_values($ret);
+ }
+
+ /**
+ * Add a user-defined IMAP flag.
+ *
+ * @param string $label The label to use for the new flag.
+ *
+ * @return string The IMAP flag name.
+ */
+ public function addFlag($label)
+ {
+ if (strlen($label) == 0) {
+ return;
+ }
+
+ $ob = new IMP_Flag_User($label);
+
+ if (!isset($this->_userflags[$ob->id])) {
+ $this->_userflags[$ob->id] = $ob;
+ $this->_save();
+ }
+
+ return $ob->imapflag;
+ }
+
+ /**
+ * Updates flag properties.
+ *
+ * @param string $key The flag key.
+ * @param string $type The property to update. Either 'bgcolor' or
+ * 'label'.
+ * @param string $data The updated data.
+ */
+ public function updateFlag($key, $type, $data)
+ {
+ if (isset($this->_flags[$key])) {
+ $ob = $this->_flags[$key];
+ } elseif (isset($this->_userflags[$key])) {
+ $ob = $this->_userflags[$key];
+ } else {
+ return;
+ }
+
+ $ob->$type = $data;
+
+ if (isset($this->_flags[$key]) && ($this->_flags[$key] == $ob)) {
+ if (isset($this->_userflags[$key])) {
+ unset($this->_userflags[$key]);
+ $this->_save();
+ }
+ } else {
+ $this->_userflags[$key] = $ob;
+ $this->_save();
+ }
+ }
+
+ /**
+ * Parse a list of flag information.
+ *
+ * @param array $opts Options:
+ * <pre>
+ * 'flags' - (array) IMAP flag info. A lowercase list of flags returned
+ * by the IMAP server.
+ * 'headers' - (Horde_Mime_Headers) Determines attachment and priority
+ * information from a headers object.
+ * 'personal' - (mixed) Personal message info. Either an array of To
+ * addresses as returned by
+ * Horde_Mime_Address::getAddressesFromObject() or the
+ * identity that matched the address list.
+ * </pre>
+ *
+ * @return array A list of IMP_Flag_Base objects.
+ */
+ public function parse(array $opts = array())
+ {
+ $opts = array_merge(array(
+ 'flags' => array(),
+ 'headers' => null,
+ 'personal' => null
+ ), $opts);
+
+ $imap = ($GLOBALS['session']->get('imp', 'protocol') == 'imap');
+ $ret = array();
+
+ foreach (array_merge($this->_flags, $this->_userflags) as $val) {
+ switch (get_class($val)) {
+ case 'IMP_Flag_System_Attachment':
+ case 'IMP_Flag_System_Encrypted':
+ case 'IMP_Flag_System_HighPriority':
+ case 'IMP_Flag_System_LowPriority':
+ case 'IMP_Flag_System_Signed':
+ if (!is_null($opts['headers']) &&
+ $val->match($opts['headers'])) {
+ $ret[] = $val;
+ }
+ break;
+
+ case 'IMP_Flag_System_Personal':
+ if (!is_null($opts['personal']) &&
+ $val->match($opts['personal'])) {
+ $ret[] = $val;
+ }
+ break;
+
+ case 'IMP_Flag_System_Unseen':
+ default:
+ if ($imap && $val->match($opts['flags'])) {
+ $ret[] = $val;
+ }
+ break;
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Process a flag ID formatted for use in form data.
+ *
+ * @param string $id The ID from form data.
+ *
+ * @return array Two element array:
+ * <pre>
+ * 'flag' - (string) The flag name.
+ * 'set' - (boolean) Whether the flag should be set or not.
+ * </pre>
+ */
+ public function parseFormId($id)
+ {
+ return (strpos($id, '0\\') === 0)
+ ? array('flag' => substr($id, 2), 'set' => false)
+ : array('flag' => $id, 'set' => true);
+ }
+
+ /**
+ * Returns a list of flags that have changed due to IMAP flag changes.
+ *
+ * @param array $flags The list of IMAP flags added/removed.
+ * @param boolean $add True if these flags were added, false if they were
+ * removed.
+ *
+ * @return array Array with two keys: 'add' and 'remove'. Each key
+ * contains a list of IMP_Flag_Base objects.
+ */
+ public function changed($flags, $add)
+ {
+ $ret = array(
+ 'add' => array(),
+ 'remove' => array()
+ );
+
+ $obs = array();
+ foreach ($flags as $val) {
+ $obs[] = $this[$val];
+ }
+
+ if ($add) {
+ $ret['add'] = $obs;
+ } else {
+ $ret['remove'] = $obs;
+ }
+
+ foreach (array_merge($this->_flags, $this->_userflags) as $val) {
+ $res = $val->changed($obs, $add);
+
+ if ($res === false) {
+ $ret['remove'][] = $val;
+ } elseif ($res === true) {
+ $ret['add'][] = $val;
+ }
+ }
+
+ return $ret;
+ }
+
+ /* ArrayAccess methods. */
+
+ /**
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->_flags[$offset]) ||
+ isset($this->_userflags[$offset]);
+ }
+
+ /**
+ */
+ public function offsetGet($offset)
+ {
+ if (isset($this->_flags[$offset])) {
+ return $this->_flags[$offset];
+ } elseif ($this->_userflags[$offset]) {
+ return $this->_userflags[$offset];
+ }
+
+ return null;
+ }
+
+ /**
+ * @throws InvalidArgumentException
+ */
+ public function offsetSet($offset, $value)
+ {
+ throw new InvalidArgumentException('Use addFlag()/updateFlag()');
+ }
+
+ /**
+ */
+ public function offsetUnset($offset)
+ {
+ if (isset($this->_userflags[$offset])) {
+ unset($this->_userflags[$offset]);
+ $this->_save();
+ }
+ }
+
+ /* Serializable methods. */
+
+ /**
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ $this->_flags,
+ $this->_userflags
+ ));
+ }
+
+ /**
+ */
+ public function unserialize($data)
+ {
+ $data = @unserialize($data);
+ if (!is_array($data)) {
+ throw new Exception('Cache invalidation.');
+ }
+
+ $this->_flags = $data[0];
+ $this->_userflags = $data[1];
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * The IMP_Imap_Flags class provides an interface to deal with display of
- * flags/labels on messages.
- *
- * Copyright 2009-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
- *
- * @author Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license http://www.fsf.org/copyleft/gpl.html GPL
- * @package IMP
- */
-class IMP_Imap_Flags
-{
- /**
- * The cached list of flags.
- *
- * @var array
- */
- protected $_flags = null;
-
- /**
- * The 'msgflags_user' preference value.
- *
- * @var array
- */
- protected $_userflags = null;
-
- /**
- * Temporary flags (i.e. flags created by other MUAs).
- *
- * @var array
- */
- protected $_tempflags = array();
-
- /**
- * Save the flag list to the prefs backend.
- *
- * @param boolean $user If true, update the user flag list. Otherwise,
- * update the system flag list.
- */
- protected function _save($user = true)
- {
- global $prefs;
-
- if ($user) {
- if (!$prefs->isLocked('msgflags_user')) {
- $prefs->setValue('msgflags_user', json_encode($this->_userflags));
- }
- } elseif (!$prefs->isLocked('msgflags')) {
- $prefs->setValue('msgflags', json_encode(array_diff_key($this->_flags, $this->_userflags)));
- }
- }
-
- /**
- * Return the raw list of flags.
- *
- * @param array $options Additional options:
- * <pre>
- * 'div' - (boolean) If true, return a DIV tag containing the code
- * necessary to display the icon.
- * DEFAULT: false
- * 'fgcolor' - (boolean) If true, add foreground color information to be
- * used for text overlay purposes.
- * DEFAULT: false
- * 'imap' - (boolean) If true, only return IMAP flags that can be set by
- * the user.
- * DEFAULT: false
- * 'mailbox' - (string) A real (not virtual) IMAP mailbox. If set, will
- * determine what flags are available in the mailbox.
- * DEFAULT: '' (no mailbox check)
- * </pre>
- *
- * @return array An array of flag information (see 'msgflags' preference
- * for format). If 'fgcolor' option is true, also adds
- * a 'f' key to each entry with foreground color info.
- * If 'div' option is true, adds a 'div' key with HTML
- * text.
- */
- public function getList($options = array())
- {
- $this->_loadList();
-
- $avail_flags = array_keys($this->_flags);
-
- $ret = $types = array();
- if (!empty($options['imap'])) {
- $types = array('imapp', 'imapu');
- }
-
- /* Reduce the list of flags for the mailbox depending on the return
- * from the PERMANENTFLAGS IMAP response. */
- if (!empty($options['mailbox'])) {
- try {
- /* Make sure we are in R/W mailbox mode (SELECT). No flags are
- * allowed in EXAMINE mode. */
- $imp_imap = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create();
- $imp_imap->openMailbox($options['mailbox'], Horde_Imap_Client::OPEN_READWRITE);
- $status = $imp_imap->status($options['mailbox'], Horde_Imap_Client::STATUS_PERMFLAGS);
-
- if (($pos = array_search('\\*', $status['permflags'])) !== false) {
- if ($GLOBALS['prefs']->getValue('show_all_flags')) {
- unset($status['permflags'][$pos]);
- $avail_flags = array_keys(array_flip(array_merge($avail_flags, $status['permflags'])));
- }
- } else {
- $avail_flags = $GLOBALS['prefs']->getValue('show_all_flags')
- ? $status['permflags']
- : array_filter(array_diff($status['permflags'], $avail_flags));
- }
- } catch (Horde_Imap_Client_Exception $e) {}
- }
-
- foreach ($avail_flags as $key) {
- if (!isset($this->_flags[$key])) {
- /* Keywords might be UTF7-IMAP encoded. */
- $ret[$key] = $this->_createEntry(Horde_String::convertCharset($key, 'UTF7-IMAP', 'UTF-8'));
- $ret[$key]['flag'] = $key;
- $this->_tempflags[$key] = $ret[$key];
- } else {
- $ret[$key] = $this->_flags[$key];
- if (!empty($options['imap']) &&
- !in_array($ret[$key]['t'], $types)) {
- unset($ret[$key]);
- } else {
- $ret[$key]['flag'] = $key;
- if (!empty($options['fgcolor'])) {
- $ret[$key] = $this->_getColor($key, $ret[$key]);
- }
- if (!empty($options['div']) && isset($ret[$key]['c'])) {
- $ret[$key]['div'] = $this->_getDiv($ret[$key]['c'], $ret[$key]['l']);
- }
- }
- }
- }
-
- return $ret;
- }
-
- /**
- * Loads the flag list from the preferences into the local cache.
- */
- protected function _loadList()
- {
- if (!is_null($this->_flags)) {
- return;
- }
-
- $this->_userflags = json_decode($GLOBALS['prefs']->getValue('msgflags_user'), true);
- $this->_flags = array_merge(
- $this->_userflags,
- json_decode($GLOBALS['prefs']->getValue('msgflags'), true)
- );
-
- /* Sanity checking. */
- if (is_array($this->_flags)) {
- $this->_flags = array_change_key_case($this->_flags, CASE_LOWER);
- } else {
- $this->_flags = array();
- $this->_save();
- }
- }
-
- /**
- * Add a user-defined IMAP flag.
- *
- * @param string $label The label to use for the new flag.
- *
- * @return string The IMAP flag name.
- */
- public function addFlag($label)
- {
- if (strlen($label) == 0) {
- return;
- }
-
- $this->_loadList();
-
- /* IMAP keywords must conform to RFC 3501 [9] (flag-keyword). Convert
- * whitespace to underscore. */
- $key = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create()->getUtils()->stripNonAtomChars(Horde_String::convertCharset(strtr($label, ' ', '_'), 'UTF-8', 'UTF7-IMAP'));
- if (!isset($this->_flags[$key])) {
- $entry = $this->_createEntry($label);
-
- $this->_flags[$key] = $entry;
- $this->_userflags[$key] = $entry;
-
- $this->_save();
- }
-
- return $key;
- }
-
- /**
- * Creates a flag entry data object.
- *
- * @param string $label The label to use for the flag.
- *
- * @return array Flag data object.
- */
- protected function _createEntry($label)
- {
- return array(
- // 'a' => These flags are not shown in mimp
- 'b' => $GLOBALS['prefs']->getValue('msgflags_color'),
- 'c' => 'flagUser',
- 'd' => true,
- 'l' => $label,
- 't' => 'imapp'
- );
- }
-
- /**
- * Updates a flag.
- *
- * @param string $label The flag label.
- * @param array $data The data to update.
- */
- public function updateFlag($label, $data)
- {
- $this->_loadList();
-
- if (isset($this->_flags[$label])) {
- foreach ($data as $key => $val) {
- $this->_flags[$label][$key] = $val;
- }
-
- $this->_save(isset($this->_updateflags[$label]));
- }
- }
-
- /**
- * Delete a flag from the list.
- *
- * @param string $label The flag label.
- *
- * @return boolean True on success.
- */
- public function deleteFlag($label)
- {
- $this->_loadList();
-
- if (isset($this->_flags[$label]) &&
- $this->_flags[$label]['l'] &&
- !empty($this->_flags[$label]['d'])) {
- $user_flag = isset($this->_userflags[$label]);
- unset($this->_flags[$label], $this->_userflags[$label]);
- $this->_save($user_flag);
- return true;
- }
-
- return false;
- }
-
- /**
- * Parse a list of flag information.
- *
- * @param array $options Additional options:
- * <pre>
- * 'div' - (boolean) If true, return a DIV tag containing the code
- * necessary to display the icon.
- * DEFAULT: false
- * 'flags' - (array) [REQUIRED] IMAP flag info. A lowercase list of flags
- * returned by the IMAP server.
- * 'headers' - (Horde_Mime_Headers) Determines attachment and priority
- * information from a headers object.
- * 'personal' - (mixed) Personal message info. Either an array of to
- * addresses as returned by
- * Horde_Mime_Address::getAddressesFromObject(), or the
- * identity that matched the address list.
- * </pre>
- *
- * @return array A list of flags with the following keys:
- * <pre>
- * 'abbrev' - (string) The abbreviation to use.
- * 'bg' - (string) The background to use.
- * 'classname' - (string) If set, the flag classname to use.
- * 'fg' - (string) The foreground color to use.
- * 'flag' - (string) The matched flag (lowercase).
- * 'div' - (string) A DIV HTML element, if 'div' option is true and a
- * classname is defined.
- * 'label' - (string) The label of the flag.
- * 'type' - (string) The flag type.
- * </pre>
- */
- public function parse($options = array())
- {
- $this->_loadList();
-
- $process = $ret = array();
- $f = $this->_flags;
-
- if (isset($options['personal'])) {
- if (is_array($options['personal'])) {
- $identity = $GLOBALS['injector']->getInstance('IMP_Identity');
- foreach ($options['personal'] as $val) {
- if ($identity->hasAddress($val['inner'])) {
- $process['personal'] = $f['personal'];
- break;
- }
- }
- } else if (!is_null($options['personal'])) {
- $process['personal'] = $f['personal'];
- }
- }
-
- if (!empty($options['headers'])) {
- $imp_hdr_ui = new IMP_Ui_Headers();
- switch ($imp_hdr_ui->getPriority($options['headers'])) {
- case 'high':
- $process['highpri'] = $f['highpri'];
- break;
-
- case 'low':
- $process['lowpri'] = $f['lowpri'];
- break;
- }
-
- if ($ctype = $options['headers']->getValue('content-type', Horde_Mime_Headers::VALUE_BASE)) {
- $imp_mbox_ui = new IMP_Ui_Mailbox();
- if ($type = $imp_mbox_ui->getAttachmentType($ctype)) {
- $process[$type] = $f[$type];
- }
- }
- }
-
- if ($GLOBALS['session']->get('imp', 'protocol') == 'imap') {
- $flaglist = empty($options['flags'])
- ? array()
- : array_map('strtolower', $options['flags']);
-
- foreach (array_merge($f, $this->_tempflags) as $k => $v) {
- if (in_array($v['t'], array('imap', 'imapp', 'imapu', 'imp'))) {
- $match = in_array($k, $flaglist);
- if (!empty($v['n'])) {
- $match = !$match;
- }
-
- if ($match) {
- $process[$k] = $v;
- }
- }
- }
- }
-
- foreach ($process as $key => $val) {
- $color = $this->_getColor($key, $val);
-
- $tmp = array(
- 'bg' => $color['b'],
- 'fg' => $color['f'],
- 'flag' => $key,
- 'label' => $val['l'],
- 'type' => $val['t']
- );
-
- if (isset($val['a'])) {
- $tmp['abbrev'] = $val['a'];
- }
-
- if (isset($val['c'])) {
- $tmp['classname'] = $val['c'];
- if (!empty($options['div'])) {
- $tmp['div'] = $this->_getDiv($val['c'], $val['l']);
- }
- }
-
- $ret[] = $tmp;
- }
-
- return $ret;
- }
-
- /**
- * Get the list of set/unset actions for use in dropdown lists.
- *
- * @param string $mbox The current mailbox.
- *
- * @return array An array with 2 elements: 'set' and 'unset'.
- */
- public function getFlagList($mbox)
- {
- $ret = array('set' => array(), 'unset' => array());
-
- foreach ($this->getList(array('imap' => true, 'mailbox' => $mbox)) as $val) {
- $tmp = array(
- 'f' => $val['flag'],
- 'l' => $val['l']
- );
-
- /* Check for 'opposite' flag actions. */
- $act1 = isset($val['n']) ? 'unset' : 'set';
- $act2 = ($act1 == 'set') ? 'unset' : 'set';
-
- $ret[$act1][] = $tmp;
- $tmp['f'] = '0\\' . $val['flag'];
- $ret[$act2][] = $tmp;
- }
-
- return $ret;
- }
-
- /**
- * Output a DIV element to display the icon.
- *
- * @param string $c A classname.
- * @param string $l The flag label.
- *
- * @return string A HTML DIV element.
- */
- protected function _getDiv($c, $l)
- {
- return '<div class="iconImg msgflags ' . $c . '" title="' . htmlspecialchars($l) . '"></div>';
- }
-
- /**
- * Process a flag ID formatted for use in form data.
- *
- * @param string $id The ID from form data.
- *
- * @return array Two element array:
- * <pre>
- * 'flag' - (string) The flag name.
- * 'set' - (boolean) Whether the flag should be set or not.
- * </pre>
- */
- public function parseFormId($id)
- {
- if (strpos($id, '0\\') === 0) {
- return array('flag' => substr($id, 2), 'set' => false);
- }
- return array('flag' => $id, 'set' => true);
- }
-
- /**
- * Given a flag/set combo, returns the text label.
- *
- * @param string $name Flag name.
- * @param boolean $set Search for set flag?
- *
- * @return string The text label.
- */
- public function getLabel($name, $set)
- {
- $flist = $this->getList();
-
- if (!isset($flist[$name])) {
- return '';
- }
-
- if (!empty($flist[$name]['n'])) {
- $set = !$set;
- }
-
- return $set
- ? $flist[$name]['l']
- : sprintf(_("Not %s"), $flist[$name]['l']);
- }
-
- /**
- * Determines the colors for an entry.
- *
- * @param string $key The flag key.
- * @param array $in The array of flag data.
- *
- * @return array $in with the 'b' and 'f' keys populated.
- */
- protected function _getColor($key, $in)
- {
- $in['f'] = '#000';
-
- if (!isset($in['b'])) {
- $in['b'] = '#fff';
- } elseif (Horde_Image::brightness($in['b']) < 128) {
- $in['f'] = '#f6f6f6';
- }
-
- return $in;
- }
-
-}
/**
* Returns mailbox/UID information for the first index.
*
- * @return array A 2-element array with the mailbox and the UID.
+ * @return boolean $all If true, returns all UIDs for the first index
+ * in an array. If false, returns the first UID for
+ * the first index as a string.
+ *
+ * @return array A 2-element array with the mailbox and the UID(s).
*/
- public function getSingle()
+ public function getSingle($all = false)
{
$val = reset($this->_indices);
- return array(key($this->_indices), reset($val));
+ return array(key($this->_indices), $all ? $val : reset($val));
+ }
+
+ /**
+ * Return a copy of the indices array.
+ *
+ * @return array The indices array (keys are mailbox names, values are
+ * arrays of UIDS).
+ */
+ public function indices()
+ {
+ /* This creates a copy of the indices array. Needed because the
+ * Iterator functions rely on pointers. */
+ return $this->_indices;
}
+ /* Countable methods. */
+
/**
* Index count.
*
return $count;
}
- /**
- * Return a copy of the indices array.
- *
- * @return array The indices array (keys are mailbox names, values are
- * arrays of UIDS).
- */
- public function indices()
- {
- /* This creates a copy of the indices array. Needed because the
- * Iterator functions rely on pointers. */
- return $this->_indices;
- }
-
/* Magic methods. */
/**
--- /dev/null
+<?php
+/**
+ * A Horde_Injector based factory for the IMP_Flags object.
+ *
+ * PHP version 5
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @link http://pear.horde.org/index.php?package=IMP
+ * @package IMP
+ */
+
+/**
+ * A Horde_Injector based factory for the IMP_Flags object.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license http://www.fsf.org/copyleft/gpl.html GPL
+ * @link http://pear.horde.org/index.php?package=IMP
+ * @package IMP
+ */
+class IMP_Injector_Factory_Flags
+{
+ /**
+ * Return the IMP_Flags instance.
+ *
+ * @return IMP_Flags The singleton instance.
+ */
+ public function create(Horde_Injector $injector)
+ {
+ try {
+ $instance = $GLOBALS['session']->get('imp', 'flags');
+ } catch (Exception $e) {
+ Horde::logMessage('Could not unserialize stored IMP_Flags object.', 'DEBUG');
+ $instance = null;
+ }
+
+ if (is_null($instance)) {
+ $instance = new IMP_Flags();
+ }
+
+ register_shutdown_function(array($this, 'shutdown'), $instance);
+
+ return $instance;
+ }
+
+ /**
+ * Store serialized version of object in the current session.
+ *
+ * @param IMP_Flags $instance Flags object.
+ */
+ public function shutdown($instance)
+ {
+ /* Only need to store the object if the object has changed. */
+ if ($instance->changed) {
+ $GLOBALS['session']->set('imp', 'flags', $instance);
+ }
+ }
+
+}
}
/**
- * Sets or clears a given flag(s) for all messages in a list of mailboxes.
+ * Adds or removes flag(s) for all messages in a list of mailboxes.
* This function works with IMAP only, not POP3.
*
- * @param array $flags The IMAP flag(s) to set or clear.
+ * @param array $flags The IMAP flag(s) to add or remove.
* @param array $mboxes The list of mailboxes to flag.
- * @param boolean $action If true, set the flag(s), otherwise, clear the
+ * @param boolean $action If true, add the flag(s), otherwise, remove the
* flag(s).
*
* @return boolean True if successful, false if not.
return $prefs->setValue('default_encrypt', $ui->vars->default_encrypt);
case 'flagmanagement':
- $this->_updateFlagManagement($ui);
- return false;
+ return $this->_updateFlagManagement($ui);
case 'initialpageselect':
return $prefs->setValue('initial_page', IMP::formMbox($ui->vars->initial_page, false));
'ImpFlagPrefs.confirm_delete' => _("Are you sure you want to delete this flag?")
));
- $msgflags_locked = $GLOBALS['prefs']->isLocked('msgflags');
- $userflags_locked = $GLOBALS['prefs']->isLocked('msgflags_user');
-
$t = $GLOBALS['injector']->createInstance('Horde_Template');
$t->setOption('gettext', true);
+ $t->set('locked', $GLOBALS['prefs']->isLocked('msgflags'));
$out = array();
- $flaglist = $GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList(array('div' => true, 'fgcolor' => true));
- foreach ($flaglist as $key => $val) {
- $hash = hash('md5', $key);
+ $flaglist = $GLOBALS['injector']->getInstance('IMP_Flags')->getList();
+ foreach ($flaglist as $val) {
+ $hash = hash('md5', $val->id);
$bgid = 'bg_' . $hash;
- $color = htmlspecialchars($val['b']);
- $label = htmlspecialchars($val['l']);
+ $color = htmlspecialchars($val->bgcolor);
+ $label = htmlspecialchars($val->label);
$bgstyle = 'background-color:' . $color;
$tmp = array();
- if ($val['t'] == 'imapp') {
+ if ($val instanceof IMP_Flag_User) {
$tmp['label'] = $label;
- $tmp['imapp'] = true;
+ $tmp['user'] = true;
$tmp['label_name'] = 'label_' . $hash;
- if ($userflags_locked) {
- $tmp['locked'] = true;
- }
} else {
$tmp['label'] = Horde::label($bgid, $label);
- $tmp['icon'] = $val['div'];
- if ($msgflags_locked) {
- $tmp['locked'] = true;
- }
+ $tmp['icon'] = $val->div;
}
- $tmp['colorstyle'] = $bgstyle . ';color:' . htmlspecialchars($val['f']);
+ $tmp['colorstyle'] = $bgstyle . ';color:' . htmlspecialchars($val->fgcolor);
$tmp['colorid'] = $bgid;
$tmp['color'] = $color;
- $tmp['flag_del'] = !empty($val['d']);
-
$out[] = $tmp;
}
$t->set('flags', $out);
$t->set('picker_img', Horde::img('colorpicker.png', _("Color Picker")));
- $t->set('userflags_notlocked', !$userflags_locked);
return $t->fetch(IMP_TEMPLATES . '/prefs/flags.html');
}
* Update IMAP flag related preferences.
*
* @param Horde_Core_Prefs_Ui $ui The UI object.
+ *
+ * @return boolean True if preferences were updated.
*/
protected function _updateFlagManagement($ui)
{
- $imp_flags = $GLOBALS['injector']->getInstance('IMP_Imap_Flags');
+ $imp_flags = $GLOBALS['injector']->getInstance('IMP_Flags');
if ($ui->vars->flag_action == 'add') {
$GLOBALS['notification']->push(sprintf(_("Added flag \"%s\"."), $ui->vars->flag_data), 'horde.success');
return;
}
- $def_color = $GLOBALS['prefs']->getValue('msgflags_color');
-
- // Don't set updated on these actions. User may want to do more actions.
- foreach ($imp_flags->getList() as $key => $val) {
- $md5 = hash('md5', $key);
+ // Don't set updated on these actions. User may want to do more
+ // actions.
+ $update = false;
+ foreach ($imp_flags->getList() as $val) {
+ $md5 = hash('md5', $val->id);
switch ($ui->vars->flag_action) {
case 'delete':
- if (($ui->vars->flag_data == ('bg_' . $md5)) &&
- $imp_flags->deleteFlag($key)) {
- $GLOBALS['notification']->push(sprintf(_("Deleted flag \"%s\"."), $val['l']), 'horde.success');
+ if ($ui->vars->flag_data == ('bg_' . $md5)) {
+ unset($imp_flags[$val->id]);
+ $GLOBALS['notification']->push(sprintf(_("Deleted flag \"%s\"."), $val->label), 'horde.success');
}
break;
default:
/* Change labels for user-defined flags. */
- if ($val['t'] == 'imapp') {
+ if ($val instanceof IMP_Flag_User) {
$label = $ui->vars->get('label_' . $md5);
- if (strlen($label) && ($label != $val['l'])) {
- $imp_flags->updateFlag($key, array('l' => $label));
+ if (strlen($label) && ($label != $val->label)) {
+ $imp_flags->updateFlag($val->id, 'label', $label);
+ $update = true;
}
}
/* Change background for all flags. */
$bg = strtolower($ui->vars->get('bg_' . $md5));
- if ((isset($val['b']) && ($bg != $val['b'])) ||
- (!isset($val['b']) && ($bg != $def_color))) {
- $imp_flags->updateFlag($key, array('b' => $bg));
+ if ($bg != $val->bgcolor) {
+ $imp_flags->updateFlag($val->id, 'bgcolor', $bg);
+ $update = true;
}
break;
}
}
+
+ return $update;
}
/* Initial page selection. */
*/
public function queryText()
{
- return sprintf(_("flagged \"%s\""), $GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getLabel($this->_data->f, $this->_data->s));
+ $imp_flags = $GLOBALS['injector']->getInstance('IMP_Flags');
+ return sprintf(_("flagged \"%s\""), $imp_flags[$this->_data->f]->getLabel($this->_data->s));
}
}
}
/**
- * Return the icon to use for a given attachment.
- *
- * @return string The mailbox display icon type (attach, encrypt,
- * signed).
- */
- public function getAttachmentType($type)
- {
- list($primary, $sub) = explode('/', $type, 2);
- if ($primary == 'multipart') {
- switch ($sub) {
- case 'signed':
- return 'signed';
-
- case 'encrypted':
- return 'encrypt';
-
- case 'alternative':
- case 'related':
- /* Treat this as no attachments. */
- break;
-
- default:
- return 'attach';
- }
- } elseif ($type == 'application/pkcs7-mime') {
- return 'encrypt';
- }
-
- return '';
- }
-
- /**
* Formats the date header.
*
* @param integer $date The UNIX timestamp.
}
/* Generate flag array. */
- $md->flags = array_keys($GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList(array('imap' => true, 'mailbox' => $is_search ? null : $mbox)));
+ $flaglist = $GLOBALS['injector']->getInstance('IMP_Flags')->getList(array(
+ 'imap' => true,
+ 'mailbox' => $is_search ? null : $mbox
+ ));
+
+ $md->flags = array();
+ foreach ($flaglist as $val) {
+ $md->flags[] = $val->imapflag;
+ }
}
/* The search query may have changed. */
}
}
- $flag_parse = $GLOBALS['injector']->getInstance('IMP_Imap_Flags')->parse(array(
+ $flag_parse = $GLOBALS['injector']->getInstance('IMP_Flags')->parse(array(
'flags' => $ob['flags'],
'headers' => $ob['headers'],
'personal' => Horde_Mime_Address::getAddressesFromObject($ob['envelope']['to'], array('charset' => $charset))
if (!empty($flag_parse)) {
$msg['flag'] = array();
foreach ($flag_parse as $val) {
- $msg['flag'][] = $val['flag'];
+ $msg['flag'][] = $val->id;
}
}
/* Get envelope/header information. We don't use flags in this
* view. */
+ $imp_contents = null;
try {
$fetch_ret = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Imap')->create()->fetch($mailbox, array(
Horde_Imap_Client::FETCH_ENVELOPE => true,
Horde_Imap_Client::FETCH_HEADERTEXT => array(array('parse' => true, 'peek' => false))
), array('ids' => array($uid)));
- } catch (Horde_Imap_Client_Exception $e) {
- $result['error'] = $error_msg;
- $result['errortype'] = 'horde.error';
- return $result;
- }
- if (!isset($fetch_ret[$uid]['headertext'])) {
- $result['error'] = $error_msg;
- $result['errortype'] = 'horde.error';
- return $result;
- }
+ if (isset($fetch_ret[$uid]['headertext'])) {
+ /* Parse MIME info and create the body of the message. */
+ $imp_contents = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Contents')->create(new IMP_Indices($mailbox, $uid));
+ }
+ } catch (Horde_Imap_Client_Exception $e) {
+ } catch (IMP_Exception $e) {}
- /* Parse MIME info and create the body of the message. */
- try {
- $imp_contents = $GLOBALS['injector']->getInstance('IMP_Injector_Factory_Contents')->create(new IMP_Indices($mailbox, $uid));
- } catch (IMP_Exception $e) {
+ if (is_null($imp_contents)) {
$result['error'] = $error_msg;
$result['errortype'] = 'horde.error';
return $result;
$msg['from'] = Horde_String::truncate($getfrom['from'], 50);
/* Get flag information. */
- $flag_parse = $injector->getInstance('IMP_Imap_Flags')->parse(array(
+ $flag_parse = $injector->getInstance('IMP_Flags')->parse(array(
'flags' => $ob['flags'],
- 'personal' => Horde_Mime_Address::getAddressesFromObject($ob['envelope']['to'], array('charset' => 'UTF-8')),
- 'priority' => $ob['headers']
+ 'headers' => $ob['headers'],
+ 'personal' => Horde_Mime_Address::getAddressesFromObject($ob['envelope']['to'], array('charset' => 'UTF-8'))
));
foreach ($flag_parse as $val) {
- if (isset($val['abbrev'])) {
- $msg['status'] .= $val['abbrev'];
- } elseif ($val['type'] == 'imapp') {
- $msg['subject'] = '*' . Horde_String::truncate($val['label'], 8) . '* ' . $msg['subject'];
+ if ($abbrev = $val->abbreviation) {
+ $msg['status'] .= $abbrev;
+ } elseif ($val instanceof IMP_Flag_User) {
+ $msg['subject'] = '*' . Horde_String::truncate($val->label, 8) . '* ' . $msg['subject'];
}
}
}
$do_filter = false;
-$imp_flags = $injector->getInstance('IMP_Imap_Flags');
+$imp_flags = $injector->getInstance('IMP_Flags');
$imp_imap = $injector->getInstance('IMP_Injector_Factory_Imap')->create();
$indices = new IMP_Indices($vars->indices);
$n_template->set('use_pop', $session->get('imp', 'protocol') == 'pop');
if (!$n_template->get('use_pop')) {
- $tmp = $imp_flags->getFlagList($search_mbox ? null : IMP::$mailbox);
- $n_template->set('flaglist_set', $tmp['set']);
- $n_template->set('flaglist_unset', $tmp['unset']);
+ $args = array(
+ 'imap' => true,
+ 'mailbox' => $search_mbox ? null : IMP::$mailbox
+ );
+
+ $form_set = $form_unset = array();
+ foreach ($imp_flags->getList($args) as $val) {
+ $form_set[] = array(
+ 'f' => $val->form_set,
+ 'l' => $val->label
+ );
+ $form_unset[] = array(
+ 'f' => $val->form_unset,
+ 'l' => $val->label
+ );
+ }
+
+ $n_template->set('flaglist_set', $form_set);
+ $n_template->set('flaglist_unset', $form_unset);
if (!$search_mbox) {
$filters = array();
} catch (Horde_Exception_HookNotSet $e) {}
$flag_parse = $imp_flags->parse(array(
- 'div' => true,
'flags' => $ob['flags'],
'headers' => $ob['headers'],
'personal' => Horde_Mime_Address::getAddressesFromObject($ob['envelope']['to'], array('charset' => 'UTF-8'))
$subject_flags = array();
foreach ($flag_parse as $val) {
- if ($val['type'] == 'imapp') {
+ if ($val instanceof IMP_Flag_User) {
$subject_flags[] = $val;
} else {
- if (isset($val['div'])) {
- $msg['status'] .= $val['div'];
- }
- if (isset($val['classname'])) {
- $msg['class'] = $val['classname'];
+ if (!$val->bgdefault) {
+ $msg['bg'] = $val->bgcolor;
}
- $msg['bg'] = $val['bg'];
+ $msg['class'] = $val->css;
+ $msg['status'] .= $val->div;
}
}
/* Add subject flags. */
foreach ($subject_flags as $val) {
- $flag_label = Horde_String::truncate($val['label'], 12);
+ $flag_label = Horde_String::truncate($val->label, 12);
- $msg['subject'] = '<span class="' . $val['classname'] . '" style="background:' . htmlspecialchars($val['bg']) . ';color:' . htmlspecialchars($val['fg']) . '" title="' . htmlspecialchars($val['label']) . '">' . htmlspecialchars($flag_label) . '</span>' . $msg['subject'];
+ $msg['subject'] = '<span class="' . $val->css . '" style="' . ($val->bgdefault ? '' : 'background:' . htmlspecialchars($val->bgcolor) . ';') . 'color:' . htmlspecialchars($val->fgcolor) . '" title="' . htmlspecialchars($val->label) . '">' . htmlspecialchars($flag_label) . '</span>' . $msg['subject'];
}
/* Set up threading tree now. */
case 'strip_attachment':
try {
$indices = $injector->getInstance('IMP_Message')->stripPart(new IMP_Indices($vars->folder, $vars->uid), $vars->id);
- $js_vars['-DimpFullmessage.strip'] = 1;
+ $js_vars['-DimpMessage.strip'] = 1;
list(,$vars->uid) = $indices->getSingle();
$notification->push(_("Attachment successfully stripped."), 'horde.success');
} catch (IMP_Exception $e) {
$scripts = array(
array('contextsensitive.js', 'horde'),
array('textarearesize.js', 'horde'),
- array('fullmessage-dimp.js', 'imp'),
+ array('message-dimp.js', 'imp'),
array('imp.js', 'imp'),
);
foreach (array('from', 'to', 'cc', 'bcc', 'replyTo', 'log', 'uid', 'mailbox') as $val) {
if (!empty($show_msg_result[$val])) {
- $js_vars['DimpFullmessage.' . $val] = $show_msg_result[$val];
+ $js_vars['DimpMessage.' . $val] = $show_msg_result[$val];
}
}
+
+$js_vars['DimpMessage.flag'] = IMP_Ajax_Application::flagEntry(array('\\seen'), true, $vars->folder, $vars->uid);
+
+if ($poll = IMP_Ajax_Application::pollEntry($vars->folder)) {
+ $js_vars['DimpMessage.poll'] = $poll;
+}
+
$js_out = Horde::addInlineJsVars($js_vars, array('ret_vars' => true));
/* Determine if compose mode is disabled. */
}
}
-$flag_parse = $injector->getInstance('IMP_Imap_Flags')->parse(array(
+$flag_parse = $injector->getInstance('IMP_Flags')->parse(array(
'flags' => $flags,
'personal' => $match_identity
));
foreach ($flag_parse as $val) {
- if (isset($val['abbrev'])) {
- $status .= $val['abbrev'];
- } elseif ($val['type'] == 'imapp') {
- if (Horde_String::length($val['label']) > 8) {
- $status .= ' *' . Horde_String::substr($val['label'], 0, 5) . '...*';
- } else {
- $status .= ' *' . $val['label'] . '*';
- }
+ if ($abbrev = $val->abbreviation) {
+ $status .= $abbrev;
+ } elseif ($val instanceof IMP_Flag_User) {
+ $status .= ' *' . Horde_String::truncate($val->label, 8) . '*';
}
}
$uid = $index_array['uid'];
$indices = new IMP_Indices($mailbox_name, $uid);
-$imp_flags = $injector->getInstance('IMP_Imap_Flags');
+$imp_flags = $injector->getInstance('IMP_Flags');
$imp_hdr_ui = new IMP_Ui_Headers();
$imp_ui = new IMP_Ui_Message();
}
$flag_parse = $imp_flags->parse(array(
- 'div' => true,
'flags' => $flags,
'personal' => $match_identity
));
$status = '';
foreach ($flag_parse as $val) {
- if ($val['type'] == 'imapp') {
- $status .= '<span class="' . $val['classname'] . '" style="background:' . htmlspecialchars($val['bg']) . ';color:' . htmlspecialchars($val['fg']) . '">' . htmlspecialchars($val['label']) . '</span>';
+ if ($val instanceof IMP_Flag_User) {
+ $status .= '<span class="' . $val->css . '" style="' . ($val->bgdefault ? '' : 'background:' . htmlspecialchars($val->bgcolor) . ';') . 'color:' . htmlspecialchars($val->fgcolor) . '">' . htmlspecialchars($val->label) . '</span>';
} else {
- $status .= $val['div'];
+ $status .= $val->div;
}
}
if (!$use_pop) {
$n_template->set('mailbox', IMP::formMbox(IMP::$mailbox, true));
- $tmp = $imp_flags->getFlagList(IMP::$mailbox);
- $n_template->set('flaglist_set', $tmp['set']);
- $n_template->set('flaglist_unset', $tmp['unset']);
+ $tmp = $imp_flags->getList(array(
+ 'imap' => true,
+ 'mailbox' => IMP::$mailbox
+ ));
+
+ $form_set = $form_unset = array();
+ foreach ($tmp as $val) {
+ $form_set[] = array(
+ 'f' => $val->form_set,
+ 'l' => $val->label
+ );
+ $form_unset[] = array(
+ 'f' => $val->form_unset,
+ 'l' => $val->label
+ );
+ }
+
+ $n_template->set('flaglist_set', $form_set);
+ $n_template->set('flaglist_unset', $form_unset);
if ($conf['user']['allow_folders']) {
$n_template->set('move', Horde::widget('#', _("Move to folder"), 'widget moveAction', '', '', _("Move"), true));
<file name="flagprefs.js" role="horde" />
<file name="folderprefs.js" role="horde" />
<file name="folders.js" role="horde" />
- <file name="fullmessage-dimp.js" role="horde" />
+ <file name="message-dimp.js" role="horde" />
<file name="imp.js" role="horde" />
<file name="login.js" role="horde" />
<file name="mailbox-dimp.js" role="horde" />
<install as="imp/js/flagprefs.js" name="js/flagprefs.js" />
<install as="imp/js/folderprefs.js" name="js/folderprefs.js" />
<install as="imp/js/folders.js" name="js/folders.js" />
- <install as="imp/js/fullmessage-dimp.js" name="js/fullmessage-dimp.js" />
+ <install as="imp/js/message-dimp.js" name="js/message-dimp.js" />
<install as="imp/js/imp.js" name="js/imp.js" />
<install as="imp/js/login.js" name="js/login.js" />
<install as="imp/js/mailbox-dimp.js" name="js/mailbox-dimp.js" />
}
if ($vars->search_criteria_flag) {
- $formdata = $injector->getInstance('IMP_Imap_Flags')->parseFormId($vars->search_criteria_flag);
+ $formdata = $injector->getInstance('IMP_Flags')->parseFormId($vars->search_criteria_flag);
$c_list[] = new IMP_Search_Element_Flag(
$formdata['flag'],
($formdata['set'] && !$vars->search_criteria_flag_not)
Horde::url('mailbox.php', true)->add('mailbox', strval($q_ob))->redirect();
}
-$flist = $injector->getInstance('IMP_Imap_Flags')->getFlagList($vars->search_mailbox);
+$flist = $injector->getInstance('IMP_Flags')->getList(array(
+ 'imap' => true,
+ 'mailbox' => $vars->search_mailbox
+));
$flag_set = array();
-foreach ($flist['set'] as $val) {
+foreach ($flist as $val) {
$flag_set[] = array(
- 'val' => $val['f'],
- 'label' => $val['l']
+ 'val' => $val->form_set,
+ 'label' => $val->label
);
}
exit;
}
-$imp_flags = $injector->getInstance('IMP_Imap_Flags');
+$imp_flags = $injector->getInstance('IMP_Flags');
$imp_search = $injector->getInstance('IMP_Search');
$vars = Horde_Variables::getDefaultVariables();
$search_mailbox = array('INBOX');
}
-$flist = $imp_flags->getFlagList($default_mailbox);
+$flist = $imp_flags->getList(array(
+ 'imap' => true,
+ 'mailbox' => $default_mailbox
+));
/* Generate the search query if 'criteria_form' is present in the form
* data. */
/* Create the flag list. */
$flag_set = array();
-foreach ($flist['set'] as $val) {
+foreach ($flist as $val) {
$flag_set[] = array(
- 'val' => rawurlencode($val['f']),
- 'label' => htmlspecialchars($val['l'])
+ 'val' => rawurlencode($val->form_set),
+ 'label' => htmlspecialchars($val->label)
);
- $types[rawurlencode($val['f'])] = 'flag';
+ $types[rawurlencode($val->form_set)] = 'flag';
}
$t->set('flist', $flag_set);
<div class="context" id="ctx_flag" style="display:none">
</div>
+<div class="context" id="ctx_flag_search" style="display:none">
+</div>
+
<div class="context" id="ctx_contacts" style="display:none">
<a id="ctx_contacts_new"><span class="iconImg"></span><?php echo _("New Message") ?></a>
<a id="ctx_contacts_add"><span class="iconImg"></span><?php echo _("Add to Address Book") ?></a>
}
/* Generate flag array. */
-foreach ($GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList(array('fgcolor' => true)) as $val) {
- $flags[$val['flag']] = array_filter(array(
- 'b' => isset($val['b']) ? $val['b'] : null,
- 'c' => $val['c'],
- 'f' => $val['f'],
- 'l' => $val['l'],
- 'n' => isset($val['n']) ? $val['n'] : null,
- // Indicate if this is a user *P*ref flag
- 'p' => intval($val['t'] == 'imapp'),
- // Indicate if this is a flag that can be *S*earched for
- 's' => intval(in_array($val['t'], array('imapp', 'imapu')))
+foreach ($GLOBALS['injector']->getInstance('IMP_Flags')->getList() as $val) {
+ $flags[$val->id] = array_filter(array(
+ // Indicate a flag that can be *a*ltered
+ 'a' => $val->canset,
+ 'b' => $val->bgdefault ? null : $val->bgcolor,
+ 'c' => $val->css,
+ 'f' => $val->fgcolor,
+ 'i' => $val->css ? null : $val->cssicon,
+ 'l' => $val->label,
+ // Indicate a flag that can be *s*earched for
+ 's' => intval($val instanceof IMP_Flag_Imap),
+ // Indicate a *u*ser flag
+ 'u' => intval($val instanceof IMP_Flag_User)
));
}
$code = $flags = array();
/* Generate flag array. */
-foreach ($GLOBALS['injector']->getInstance('IMP_Imap_Flags')->getList(array('fgcolor' => true)) as $val) {
- $flags[$val['flag']] = array_filter(array(
- 'b' => isset($val['b']) ? $val['b'] : null,
- 'c' => $val['c'],
- 'f' => $val['f'],
- 'l' => $val['l'],
- 'n' => isset($val['n']) ? $val['n'] : null,
- // Indicate if this is a user *P*ref flag
- 'p' => intval($val['t'] == 'imapp'),
- // Indicate if this is a flag that can be *S*earched for
- 's' => intval(in_array($val['t'], array('imapp', 'imapu')))
+foreach ($GLOBALS['injector']->getInstance('IMP_Flags')->getList() as $val) {
+ $flags[$val->id] = array_filter(array(
+ 'b' => $val->bgdefault ? null : $val->bgcolor,
+ 'c' => $val->css,
+ 'f' => $val->fgcolor,
+ 'i' => $val->css ? null : $val->cssicon,
+ 'l' => $val->label,
+ // Indicate if this is a flag that can be *s*earched for
+ 's' => intval($val instanceof IMP_Flag_Imap),
+ // Indicate if this is a *u*ser flag
+ 'u' => intval($val instanceof IMP_Flag_User)
));
}
<loop:flags>
<tr>
<td>
-<if:flags.imapp>
-<if:flags.locked>
+<if:flags.user>
+<if:locked>
<tag:flags.label />
-<else:flags.locked>
+<else:locked>
<input name="<tag:flags.label_name />" value="<tag:flags.label />" />
-</else:flags.locked></if:flags.locked>
-<else:flags.imapp>
+</else:locked></if:locked>
+<else:flags.user>
<tag:flags.label />
-</else:flags.imapp></if:flags.imapp>
+</else:flags.user></if:flags.user>
</td>
<td class="flagicon">
-<if:flags.imapp><else:flags.imapp>
+<if:flags.user><else:flags.user>
<tag:flags.icon />
-</else:flags.imapp></if:flags.imapp>
+</else:flags.user></if:flags.user>
</td>
<td>
-<if:flags.locked><else:flags.locked>
+<if:locked><else:locked>
<input type="hidden" id="<tag:flags.colorid />" name="<tag:flags.colorid />" value="<tag:flags.color />" />
<div class="iconImg msgflags flagUser" style="<tag:flags.colorstyle />"></div>
<a class="flagcolorpicker" href="#"><tag:picker_img /></a>
-<if:flags.flag_del>
+<if:flags.user>
<a class="flagdelete" href="#"><span class="iconImg deleteImg"></span></a>
-</if:flags.flag_del>
-</else:flags.locked></if:flags.locked>
+</if:flags.user>
+</else:locked></if:locked>
</td>
</tr>
</loop:flags>
</tbody>
</table>
-<if:userflags_notlocked>
+<if:locked><else:locked>
<div>
<input id="new_button" type="button" class="button" value="<gettext>New Flag</gettext>" />
</div>
-</if:userflags_notlocked>
+</else:locked></if:locked>
#ctx_folderopts_reload span.iconImg {
background-image: url("../graphics/reload.png");
}
-#ctx_flag span.iconImg.flagUser {
+#ctx_flag span.iconImg.flagUser, #ctx_flag_search span.iconImg.flagUser {
border: 1px black solid;
height: 15px;
width: 15px;
tr.flagUnseen {
font-weight: bold;
}
+span.iconImg.flagSeen {
+ background-image: url("graphics/mail_seen.png");
+}
div.msgflags.flagUnseen, span.iconImg.flagUnseen {
background-image: url("graphics/mail_unseen.png");
}
div.msgflags.flagAttachmsg {
background-image: url("graphics/attachment.png");
}
+span.iconImg.flagSeen {
+ background-image: url("graphics/mail_seen.png");
+}
div.msgflags.flagUnseen, span.iconImg.flagUnseen {
background-image: url("graphics/mail_unseen.png");
}