if (Horde_Util::getPost('unsub')) {
$mask |= IMP_Imap_Tree::FLIST_UNSUB;
}
- $result = IMP_Dimp::getFolderResponse($imptree, array('a' => $imptree->folderList($mask), 'c' => array(), 'd' => array()));
+
+ if (!Horde_Util::getPost('all')) {
+ $mask |= IMP_Imap_Tree::FLIST_NOCHILDREN;
+ if (Horde_Util::getPost('initial') || Horde_Util::getPost('reload')) {
+ $mask |= IMP_Imap_Tree::FLIST_ANCESTORS | IMP_Imap_Tree::FLIST_SAMELEVEL;
+ }
+ }
+
+ $folder_list = array();
+ foreach (Horde_Serialize::unserialize($mbox, Horde_Serialize::JSON) as $val) {
+ $folder_list += $imptree->folderList($mask, $val);
+ }
+
+ /* Add special folders explicitly to the initial folder list, since they
+ * are ALWAYS displayed and may appear outside of the folder slice
+ * requested. */
+ if (Horde_Util::getPost('initial')) {
+ foreach ($imptree->getSpecialMailboxes() as $val) {
+ if (!is_array($val)) {
+ $val = array($val);
+ }
+
+ foreach ($val as $val2) {
+ if (!isset($folder_list[$val2])) {
+ $folder_list[$val2] = $imptree->element($val2);
+ }
+ }
+ }
+ }
+
+ $result = IMP_Dimp::getFolderResponse($imptree, array('a' => array_values($folder_list), 'c' => array(), 'd' => array()));
$quota = _getQuota();
if (!is_null($quota)) {
case 'ctx_folderopts_expand':
case 'ctx_folderopts_collapse':
- $('normalfolders').select('LI.folder').each(function(f) {
- this._toggleSubFolder(f, id == 'ctx_folderopts_expand' ? 'exp' : 'col', true);
- }, this);
+ this._toggleSubFolder($('normalfolders'), id == 'ctx_folderopts_expand' ? 'expall' : 'colall', true);
break;
case 'ctx_folderopts_reload':
case 'ctx_container_collapse':
case 'ctx_folder_expand':
case 'ctx_folder_collapse':
- tmp = baseelt.up('LI');
- [ tmp, $(this.getSubFolderId(tmp.readAttribute('id'))).select('LI.folder') ].flatten().each(function(f) {
- this._toggleSubFolder(f, (id == 'ctx_container_expand' || id == 'ctx_folder_expand') ? 'exp' : 'col', true);
- }, this);
+ this._toggleSubFolder(baseelt.up('LI').next(), (id == 'ctx_container_expand' || id == 'ctx_folder_expand') ? 'expall' : 'colall', true);
break;
case 'ctx_message_spam':
}
},
- _folderLoadCallback: function(r)
+ _folderLoadCallback: function(r, callback)
{
this._folderCallback(r);
+ if (callback) {
+ callback();
+ }
+
var nf = $('normalfolders'),
nfheight = nf.getStyle('max-height');
_toggleSubFolder: function(base, mode, noeffect)
{
- // Make sure all subfolders are expanded.
- // The last 2 elements of ancestors() are the BODY and HTML tags -
- // don't need to parse through them.
- var subs = (mode == 'exp')
- ? base.ancestors().slice(0, -2).reverse().findAll(function(n) { return n.hasClassName('subfolders'); })
- : [ base.next('.subfolders') ];
+ var need = [], subs = [];
- subs.compact().each(function(s) {
+ if (mode == 'expall' || mode == 'colall') {
+ if (base.hasClassName('subfolders')) {
+ subs.push(base);
+ }
+ subs = subs.concat(base.select('.subfolders'));
+ } else if (mode == 'exp') {
+ // If we are explicitly expanding ('exp'), make sure all parent
+ // subfolders are expanded.
+ // The last 2 elements of ancestors() are the BODY and HTML tags -
+ // don't need to parse through them.
+ subs = base.ancestors().slice(0, -2).reverse().findAll(function(n) { return n.hasClassName('subfolders'); });
+ } else {
+ subs = [ base.next('.subfolders') ];
+ }
+
+ if (!subs) {
+ return;
+ }
+
+ if (mode == 'tog' || mode == 'expall') {
+ subs.compact().each(function(s) {
+ if (!s.visible() && !s.down().childElements().size()) {
+ need.push(s.previous().retrieve('mbox'));
+ }
+ });
+
+ if (need.size()) {
+ this._listFolders({
+ all: Number(mode == 'expall'),
+ callback: this._toggleSubFolder.bind(this, base, mode, noeffect),
+ view: need
+ });
+ return;
+ }
+ }
+
+ subs.each(function(s) {
if (mode == 'tog' ||
- (mode == 'exp' && !s.visible()) ||
- (mode == 'col' && s.visible())) {
+ ((mode == 'exp' || mode == 'expall') && !s.visible()) ||
+ ((mode == 'col' || mode == 'colall') && s.visible())) {
s.previous().down().toggleClassName('exp').toggleClassName('col');
if (noeffect) {
});
}
}
- }, this);
+ });
+ },
+
+ _listFolders: function(params)
+ {
+ var cback;
+
+ params = params || {};
+ params.unsub = Number(this.showunsub);
+ if (!Object.isArray(params.view)) {
+ params.view = [ params.view ];
+ }
+ params.view = params.view.toJSON();
+
+ if (params.callback) {
+ cback = function(func, r) { this._folderLoadCallback(r, func); }.bind(this, params.callback);
+ delete params.callback;
+ } else {
+ cback = this._folderLoadCallback.bind(this);
+ }
+
+ DimpCore.doAction('ListFolders', params, { callback: cback });
},
// Folder actions.
submbox = $(submboxid),
title = ob.t || ob.m;
+ if ($(fid)) {
+ return;
+ }
+
if (ob.v) {
ftype = ob.co ? 'scontainer' : 'virtual';
title = label;
this.deleteFolderElt(elt.readAttribute('id'), true);
}, this);
- DimpCore.doAction('ListFolders', { unsub: Number(this.showunsub) }, { callback: this._folderLoadCallback.bind(this) });
+ this._listFolders({ reload: 1, view: this.folder });
},
subscribeFolder: function(f, sub)
$('dimpmain').setStyle({ left: ($('sidebar').clientWidth + this.splitbar.clientWidth) + 'px' });
- /* Create the folder list. Any pending notifications will be caught
- * via the return from this call. */
- DimpCore.doAction('ListFolders', {}, { callback: this._folderLoadCallback.bind(this) });
-
/* Init quicksearch. These needs to occur before loading the message
* list since it may be disabled if we are in a search mailbox. */
if ($('qsearch')) {
if (!tmp.empty() && tmp.startsWith('#')) {
tmp = (tmp.length == 1) ? "" : tmp.substring(1);
}
+
if (!tmp.empty()) {
this.go(unescape(tmp));
} else if (DIMP.conf.login_view == 'inbox') {
this.loadMailbox('INBOX', { background: true });
}
+ /* Create the folder list. Any pending notifications will be caught
+ * via the return from this call. */
+ this._listFolders({ initial: 1, view: this.folder} );
+
this._setQsearchText(true);
/* Add popdown menus. Check for disabled compose at the same time. */
const FLIST_OB = 8;
const FLIST_ELT = 16;
const FLIST_NOCHILDREN = 32;
+ const FLIST_ANCESTORS = 64;
+ const FLIST_SAMELEVEL = 128;
/* Add null to folder key since it allows us to sort by name but
* never conflict with an IMAP mailbox. */
* IMP_Imap_Tree::FLIST_OB - Return full tree object.
* IMP_Imap_Tree::FLIST_ELT - Return element object.
* IMP_Imap_Tree::FLIST_NOCHILDREN - Don't show child elements.
+ * IMP_Imap_Tree::FLIST_ANCESTORS - Include ancestors.
+ * IMP_Imap_Tree::FLIST_SAMELEVEL - Also return mailboxes at the same
+ * level as $base.
* </pre>
* @param string $base Return all mailboxes below this element.
*
* @return array Either an array of IMAP mailbox names or an array of
- * objects (if FLIST_OB ot FLIST_ELT is specified).
+ * objects (if FLIST_OB ot FLIST_ELT is specified). Keys
+ * are the mailbox name.
*/
public function folderList($mask = 0, $base = null)
{
- $baseindex = null;
+ $baseelt = $baseindex = null;
$ret_array = array();
$diff_unsub = (($mask & self::FLIST_UNSUB) != $this->_showunsub)
// Search to base element.
if (!is_null($base)) {
- while ($mailbox && $mailbox['v'] != $base) {
+ while ($mailbox && strcasecmp($base, $mailbox['v']) !== 0) {
$mailbox = $this->next(self::NEXT_SHOWCLOSED);
}
+
if ($mailbox) {
$baseindex = count($this->_currstack);
- $baseparent = $this->_currparent;
- $basekey = $this->_currkey;
- $mailbox = $this->next(self::NEXT_SHOWCLOSED);
+
+ if ($mask & self::FLIST_SAMELEVEL) {
+ --$baseindex;
+ if ($baseindex >= 0) {
+ $basekey = $this->_currstack[$baseindex]['k'];
+ $baseparent = $this->_currstack[$baseindex]['p'];
+ $baseelt = $mailbox = $this->_tree[$this->_parent[$this->_currparent][0]];
+ } else {
+ $mailbox = $this->reset();
+ }
+ $this->_currkey = 0;
+ } else {
+ $basekey = $this->_currkey;
+ $baseparent = $this->_currparent;
+ $mailbox = $this->next(self::NEXT_SHOWCLOSED);
+ }
}
}
if ($mailbox) {
do {
if (!is_null($baseindex) &&
+ ($baseindex >= 0) &&
(!isset($this->_currstack[$baseindex]) ||
($this->_currstack[$baseindex]['k'] != $basekey) ||
($this->_currstack[$baseindex]['p'] != $baseparent))) {
!$this->isContainer($mailbox)) &&
(($mask & self::FLIST_VFOLDER) ||
!$this->isVFolder($mailbox))) {
- $ret_array[] = ($mask & self::FLIST_OB)
+ $ret_array[$mailbox['v']] = ($mask & self::FLIST_OB)
? $mailbox
: (($mask & self::FLIST_ELT) ? $this->element($mailbox['v']) : $mailbox['v']);
}
$this->showUnsubscribed($diff_unsub);
}
- return $ret_array;
+ return (!is_null($baseelt) && ($mask & self::FLIST_ANCESTORS))
+ ? array_merge($this->folderList($mask, $baseelt['p']), $ret_array)
+ : $ret_array;
}
/**