* Create code needed for source selection.
*
* @param Horde_Core_Prefs_Ui $ui The UI object.
- * @param array $data REQUIRED data items:
+ * @param array $data Data items:
* <pre>
- * 'mainlabel'
- * 'selected'
- * 'selectlabel'
- * 'unselected'
- * 'unselectlabel'
+ * 'mainlabel' - (string) Main label.
+ * 'selectlabel' - (array) Selected label.
+ * 'sourcelabel' - (string) [OPTIONAL] Source selection label.
+ * 'sources' - (array) List of sources - keys are source names. Each
+ * source is an array with two entries - selected and
+ * unselected.
+ * 'unselectlabel' - (array) Unselected label.
* </pre>
*
* @return string HTML UI code.
static public function source($ui, $data = array())
{
$t = $GLOBALS['injector']->createInstance('Horde_Template');
- $t->setOption('gettext', true);
$t->set('mainlabel', $data['mainlabel']);
$t->set('selectlabel', $data['selectlabel']);
$t->set('unselectlabel', $data['unselectlabel']);
- $unselected = array();
- foreach ($data['unselected'] as $key => $val) {
- $unselected[] = array(
- 'l' => $val,
- 'v' => $key
- );
+ $sources = array();
+ foreach ($data['sources'] as $key => $val) {
+ $selected = $unselected = array();
+
+ foreach ($data['selected'] as $key2 => $val2) {
+ $selected[] = array(
+ 'l' => $val2,
+ 'v' => $key2
+ );
+ }
+
+ foreach ($data['unselected'] as $key2 => $val2) {
+ $unselected[] = array(
+ 'l' => $val2,
+ 'v' => $key2
+ );
+ }
+
+ $sources[$key] = array($selected, $unselected);
}
- $t->set('unselected', $unselected);
-
- $selected = array();
- foreach ($data['selected'] as $key => $val) {
- $selected[] = array(
- 'l' => $val,
- 'v' => $key
- );
+
+ if (count($sources) == 1) {
+ $val = reset($sources);
+ $t->set('selected', $val[0]);
+ $t->set('unselected', $val[1]);
+ } else {
+ $js = array();
+ foreach ($sources as $key => $val) {
+ $js[] = array(
+ 'selected' => $val[0],
+ 'source' => $key,
+ 'unselected' => $val[1]
+ );
+ }
+ Horde::addInlineScript(array(
+ 'HordeSourceSelectPrefs.source_list = ' . Horde_Serialize::serialize($js, Horde_Serialize::JSON, Horde_Nls::getCharset())
+ ));
}
- $t->set('selected', $selected);
$t->set('addimg', Horde::img(isset($GLOBALS['nls']['rtl'][$GLOBALS['language']]) ? 'lhand.png' : 'rhand.png', _("Add source")));
$t->set('removeimg', Horde::img(isset($GLOBALS['nls']['rtl'][$GLOBALS['language']]) ? 'rhand.png' : 'lhand.png', _("Remove source")));
if (!empty($selected) || !empty($unselected)) {
$out = Horde_Core_Prefs_Ui_Widgets::source($ui, array(
'mainlabel' => _("Choose the order of address books to search when expanding addresses."),
- 'selected' => $selected,
'selectlabel' => _("Selected address books:"),
- 'unselected' => $unselected,
+ 'sources' => array(array(
+ 'selected' => $selected,
+ 'unselected' => $unselected
+ )),
'unselectlabel' => _("Available address books:")
));
'column' => _("User Interface"),
'label' => _("File Display"),
'desc' => _("Change your file sorting options."),
- 'members' => array('show_dotfiles', 'sortdirsfirst', 'columnselect',
- 'sortby', 'sortdir', 'perpage'));
+ 'members' => array(
+ 'show_dotfiles', 'sortdirsfirst', 'columnselect', 'sortby', 'sortdir',
+ 'perpage'
+ )
+);
$prefGroups['settings'] = array(
'column' => _("User Interface"),
// show dotfiles?
$_prefs['show_dotfiles'] = array(
'value' => 1,
- 'locked' => false,
- 'shared' => false,
'type' => 'checkbox',
'desc' => _("Show dotfiles?")
);
// columns selection widget
$_prefs['columnselect'] = array(
- 'locked' => false,
'type' => 'special'
);
// columns to be displayed
$_prefs['columns'] = array(
- 'value' => "ftp\ttype\tname\tdownload\tmodified\tsize\tpermission\towner\tgroup",
- 'locked' => false,
- 'shared' => false,
- 'type' => 'implicit'
+ 'value' => "ftp\ttype\tname\tdownload\tmodified\tsize\tpermission\towner\tgroup"
);
// user preferred sorting column
$_prefs['sortby'] = array(
'value' => Gollem::SORT_TYPE,
- 'locked' => false,
- 'shared' => false,
'type' => 'enum',
'enum' => array(
Gollem::SORT_TYPE => _("File Type"),
// user preferred sorting direction
$_prefs['sortdir'] = array(
'value' => 0,
- 'locked' => false,
- 'shared' => false,
'type' => 'enum',
'enum' => array(
Gollem::SORT_ASCEND => _("Ascending"),
// always sort directories before files
$_prefs['sortdirsfirst'] = array(
'value' => 0,
- 'locked' => false,
- 'shared' => false,
'type' => 'checkbox',
'desc' => _("List folders first?")
);
// number of items per page
$_prefs['perpage'] = array(
'value' => 20,
- 'locked' => false,
- 'shared' => true,
'type' => 'number',
'desc' => _("Items per page")
);
// user preferred recursive deletes
$_prefs['recursive_deletes'] = array(
'value' => 'disabled',
- 'locked' => false,
- 'shared' => false,
'type' => 'enum',
'enum' => array(
'disabled' => _("No"),
+++ /dev/null
-/**
- * Provides the javascript for the gollem column select preferences page.
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- */
-
-var columns = [];
-
-function selectSource()
-{
- var f = document.prefs;
- var fieldString = '';
-
- while (f.unselected_columns.length > 1) {
- f.unselected_columns.options[f.unselected_columns.length - 1] = null;
- }
- while (f.selected_columns.length > 1) {
- f.selected_columns.options[f.selected_columns.length - 1] = null;
- }
-
- if (f.source.selectedIndex < 1) {
- return;
- }
- var source = f.source.selectedIndex - 1;
-
- var selected = [];
- var unselected = [];
- for (var i = 1; i < columns[source].length; i++) {
- if (columns[source][i][2]) {
- selected[columns[source][i][3]] = [columns[source][i][1], columns[source][i][0]];
- } else {
- unselected[unselected.length] = [columns[source][i][1], columns[source][i][0]];
- }
- }
- for (i = 0; i < selected.length; i++) {
- f.selected_columns.options[i + 1] = new Option(selected[i][0], selected[i][1]);
- }
- for (i = 0; i < unselected.length; i++) {
- f.unselected_columns.options[i + 1] = new Option(unselected[i][0], unselected[i][1]);
- }
-}
-
-function deselectHeaders()
-{
- document.prefs.unselected_columns[0].selected = false;
- document.prefs.selected_columns[0].selected = false;
-}
-
-function resetHidden()
-{
- var tmp = '';
- for (var i = 0; i < columns.length; i++) {
- if (i > 0) {
- tmp += '\n';
- }
- tmp += columns[i][0];
- for (var j = 1; j < columns[i].length; j++) {
- if (columns[i][j][2]) {
- tmp += '\t' + columns[i][j][0];
- }
- }
- }
- document.prefs.columns.value = tmp;
-}
-
-function addColumn()
-{
- var f = document.prefs;
- var source = f.source.selectedIndex - 1;
-
- for (i = 1; i < f.unselected_columns.length; i++) {
- if (f.unselected_columns[i].selected) {
- for (var j = 1; j < columns[source].length; j++) {
- if (columns[source][j][0] == f.unselected_columns[i].value) {
- columns[source][j][2] = true;
- }
- }
- f.selected_columns[f.selected_columns.length] = new Option(f.unselected_columns[i].text, f.unselected_columns[i].value);
- f.unselected_columns[i] = null;
- i--;
- }
- }
-
- resetHidden();
-}
-
-function removeColumn()
-{
- var f = document.prefs;
- var source = f.source.selectedIndex - 1;
-
- for (i = 1; i < f.selected_columns.length; i++) {
- if (f.selected_columns[i].selected) {
- for (var j = 1; j < columns[source].length; j++) {
- if (columns[source][j][0] == f.selected_columns[i].value) {
- columns[source][j][2] = false;
- }
- }
- f.unselected_columns[f.unselected_columns.length] = new Option(f.selected_columns[i].text, f.selected_columns[i].value)
- f.selected_columns[i] = null;
- i--;
- }
- }
-
- resetHidden();
-}
-
-function moveColumnUp()
-{
- var f = document.prefs;
- var sel = f.selected_columns.selectedIndex;
- var source = f.source.selectedIndex - 1;
-
- if (sel <= 1 || f.selected_columns.length <= 2) return;
-
- // deselect everything but the first selected item
- f.selected_columns.selectedIndex = sel;
- var up = f.selected_columns[sel].value;
-
- tmp = [];
- for (i = 1; i < f.selected_columns.length; i++) {
- tmp[i - 1] = new Option(f.selected_columns[i].text, f.selected_columns[i].value)
- }
-
- for (i = 0; i < tmp.length; i++) {
- if (i + 1 == sel - 1) {
- f.selected_columns[i + 1] = tmp[i + 1];
- } else if (i + 1 == sel) {
- f.selected_columns[i + 1] = tmp[i - 1];
- } else {
- f.selected_columns[i + 1] = tmp[i];
- }
- }
-
- f.selected_columns.selectedIndex = sel - 1;
-
- for (i = 2; i < columns[source].length - 1; i++) {
- if (columns[source][i][0] == up) {
- column = columns[source][i];
- columns[source][i] = columns[source][i - 1];
- columns[source][i - 1] = column;
- }
- }
-
- resetHidden();
-}
-
-function moveColumnDown()
-{
- var f = document.prefs;
- var sel = f.selected_columns.selectedIndex;
- var source = f.source.selectedIndex - 1;
-
- if (sel == -1 || f.selected_columns.length <= 2 || sel == f.selected_columns.length - 1) return;
-
- // deselect everything but the first selected item
- f.selected_columns.selectedIndex = sel;
- var down = f.selected_columns[sel].value;
-
- tmp = [];
- for (i = 1; i < f.selected_columns.length; i++) {
- tmp[i - 1] = new Option(f.selected_columns[i].text, f.selected_columns[i].value)
- }
-
- for (i = 0; i < tmp.length; i++) {
- if (i + 1 == sel) {
- f.selected_columns[i + 1] = tmp[i + 1];
- } else if (i + 1 == sel + 1) {
- f.selected_columns[i + 1] = tmp[i - 1];
- } else {
- f.selected_columns[i + 1] = tmp[i];
- }
- }
-
- f.selected_columns.selectedIndex = sel + 1;
-
- for (i = columns[source].length - 2; i > 0; i--) {
- if (columns[source][i][0] == down || columns[source][i + 1][0] == down) {
- column = columns[source][i];
- columns[source][i] = columns[source][i + 1];
- columns[source][i + 1] = column;
- }
- }
-
- resetHidden();
-}
}
/**
+ * Code to run on init when viewing prefs for this application.
+ *
+ * @param Horde_Core_Prefs_Ui $ui The UI object.
+ */
+ public function prefsInit($ui)
+ {
+ global $prefs;
+
+ switch ($ui->group) {
+ case 'display':
+ if (!$prefs->isLocked('columns')) {
+ Horde_Core_Prefs_Ui_Widgets::sourceInit($ui);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Generate code used to display a special preference.
+ *
+ * @param Horde_Core_Prefs_Ui $ui The UI object.
+ * @param string $item The preference name.
+ *
+ * @return string The HTML code to display on the options page.
+ */
+ public function prefsSpecial($ui, $item)
+ {
+ switch ($item) {
+ case 'columnselect':
+ $cols = Gollem::displayColumns();
+ $sources = array();
+
+ foreach ($GLOBALS['gollem_backends'] as $source => $info) {
+ $selected = $unselected = array();
+ $selected_list = isset($cols[$source])
+ ? array_flip($cols[$source]) :
+ : array();
+
+ foreach ($info['attributes'] as $column) {
+ if (isset($selected_list[$column])) {
+ $selected[] = array($column, $column);
+ } else {
+ $unselected[] = array($column, $column);
+ }
+ }
+ $sources[$source] = array(
+ 'selected' => $selected,
+ 'unselected' => $unselected,
+ );
+ }
+
+ return Horde_Core_Prefs_Ui_Widgets::source($ui, array(
+ 'mainlabel' => _("Choose which address books to display, and in what order:"),
+ 'selectlabel' => _("These addressbooks will display in this order:"),
+ 'sourcelabel' => _("Select a backend:"),
+ 'sources' => $foo,
+ 'unselectlabel' => _("Address books that will not be displayed:")
+ ));
+ }
+
+ return '';
+ }
+
+ /**
* Special preferences handling on update.
*
* @param Horde_Core_Prefs_Ui $ui The UI object.
{
switch ($item) {
case 'columnselect':
- if (isset($ui->vars->columns)) {
- $GLOBALS['prefs']->setValue('columns', $ui->vars->columns);
+ if (isset($ui->vars->sources)) {
+ $pref = array();
+ foreach (Horde_Serialize::unserialize($ui->vars->sources, Horde_Serialize::JSON) as $val) {
+ $pref[] = implode("\t", array_merge($val[0], $val[1]));
+ }
+ $GLOBALS['prefs']->setValue('columns', implode("\n", $pref));
return true;
}
break;
}
+
+ return false;
}
/**
+++ /dev/null
-<input type="hidden" name="columns" value="<tag:columns />" />
-
-<div>
- <select name="source" onchange="if (document.prefs.source.selectedIndex != 0) selectSource();">
- <option value=""><gettext>Please select a backend:</gettext></option>
-<loop:be>
- <option value="<tag:be.val />"><tag:be.label /></option>
-</loop:be>
- </select>
-</div>
-
-<gettext>Choose the columns to display in the file manager.</gettext>
-
-<br />
-
-<table>
- <tr>
- <td>
- <select name="unselected_columns" multiple="multiple" size="5" width="20" onchange="deselectHeaders();">
- <option value=""><gettext>Available Columns:</gettext></option>
- </select>
- </td>
- <td>
- <a href="#" onclick="addColumn(); return false;"><tag:add /></a>
- <br />
- <a href="#" onclick="removeColumn(); return false;"><tag:remove /></a>
- </td>
- <td>
- <select name="selected_columns" multiple="multiple" size="5" width="20" onchange="deselectHeaders();">
- <option value=""><gettext>Selected Columns:</gettext></option>
- </select>
- </td>
- <td>
- <a href="#" onclick="moveColumnUp(); return false;"><tag:left /></a>
- <br />
- <a href="#" onclick="moveColumnDown(); return false;"><tag:right /></a>
- </td>
- </tr>
-</table>
+++ /dev/null
-<?php
-/**
- * Horde_Prefs_Ui:: always calls a .inc file, so we need to use this file to
- * generate the data needed to display the template.
- */
-
-if (!$prefs->isLocked('columns')) {
- $js_columns = '';
- $sources = Gollem::displayColumns();
- $source_count = 0;
-
- foreach ($GLOBALS['gollem_backends'] as $source => $info) {
- $js_columns .= "columns[$source_count] = [];";
- $js_columns .= "columns[$source_count][0] = '$source';";
-
- $column_count = 1;
- $selected = isset($sources[$source]) ? array_flip($sources[$source]) : array();
- foreach ($info['attributes'] as $null => $column) {
- $marked = isset($selected[$column]) ? 'true' : 'false';
- $js_columns .= "columns[$source_count][$column_count] = ['$column', '" . addslashes($column) . "', $marked, " . (($marked === 'true') ? $selected[$column] : 'null') . "];";
- ++$column_count;
- }
- ++$source_count;
- }
-
- Horde::addScriptFile('columnselect.js', 'gollem');
- Horde::addInlineScript($js_columns);
-
- $t = $injector->createInstance('Horde_Template');
- $t->setOption('gettext', true);
-
- $be = array();
- foreach ($GLOBALS['gollem_backends'] as $key => $info) {
- $be[] = array('val' => $key, 'label' => $info['name']);
- }
- $t->set('be', $be);
-
- $t->set('columns', $prefs->getValue('columns'));
-
- $t->set('add', Horde::img('rhand.png', _("Add column")));
- $t->set('remove', Horde::img('lhand.png', _("Remove column")));
- $t->set('left', Horde::img('nav/up.png', _("Move left")));
- $t->set('right', Horde::img('nav/down.png', _("Move right")));
-
- echo $t->fetch(GOLLEM_TEMPLATES . '/prefs/columnselect.html');
-}
/**
* Provides the javascript for managing the source selection widget.
*
- * See the enclosed file COPYING for license information (GPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*/
var HordeSourceSelectPrefs = {
- resetHidden: function()
+ // Vars defaulting to null: source_list
+
+ setSourcesHidden: function()
{
- $('sources').setValue($F('selected_sources').toJSON());
+ var out = [], ss;
+
+ if (this.source_list) {
+ ss = $F('source_select');
+ if (ss) {
+ this.source_list.each(function(s) {
+ if (s.source == ss) {
+ s.selected = $F('selected_sources');
+ }
+ out.push([ s.source, s.selected ]);
+ });
+ $('sources').setValue(out.toJSON());
+ }
+ } else {
+ $('sources').setValue($F('selected_sources').toJSON());
+ }
},
moveAction: function(from, to)
}
});
- this.resetHidden();
+ this.setSourcesHidden();
},
moveSource: function(e, mode)
break;
}
- this.resetHidden();
+ this.setSourcesHidden();
e.stop();
},
- onDomLoad: function()
+ changeSource: function()
{
- this.resetHidden();
+ var source,
+ sel = $('selected_sources'),
+ ss = $('source_select'),
+ unsel = $('unselected_sources'),
+ val = $F(ss);
+
+ sel.down().siblings().invoke('remove');
+ unsel.down().siblings().invoke('remove');
- if ($('unselected_sources')) {
- $('addsource').observe('click', this.moveAction.bind(this, 'unselected_sources', 'selected_sources'));
- $('removesource').observe('click', this.moveAction.bind(this, 'selected_sources', 'unselected_sources'));
- $('moveup').observe('click', this.moveSource.bindAsEventListener(this, 'up'));
- $('movedown').observe('click', this.moveSource.bindAsEventListener(this, 'down'));
+ if (val) {
+ source = this.source_list.find(function(s) {
+ return val == s.source;
+ });
+ source.selected.each(function(s) {
+ sel.insert(new Option(s.v, s.l));
+ });
+ source.unselected.each(function(u) {
+ unsel.insert(new Option(s.v, s.l));
+ });
}
+ },
+
+ onDomLoad: function()
+ {
+ if (this.source_list) {
+ $('source_select').observe('change', this.changeSource.bind(this));
+ }
+
+ this.setSourcesHidden();
+
+ $('addsource').observe('click', this.moveAction.bind(this, 'unselected_sources', 'selected_sources'));
+ $('removesource').observe('click', this.moveAction.bind(this, 'selected_sources', 'unselected_sources'));
+ $('moveup').observe('click', this.moveSource.bindAsEventListener(this, 'up'));
+ $('movedown').observe('click', this.moveSource.bindAsEventListener(this, 'down'));
}
};
<tag:mainlabel />
</p>
+<if:source_select>
+ <div>
+ <select id="source_select" name="source_select">
+ <option value=""><tag:sourcelabel /></option>
+ </select>
+ </div>
+</if:source_select>
+
<table>
<tr>
<td>
<label for="unselected_sources" class="hidden"><tag:unselectlabel /></label>
<select id="unselected_sources" name="unselected_sources" multiple="multiple" size="5">
<option class="control" disabled="disabled" value=""><tag:unselectlabel /></option>
+<if:unselected>
<loop:unselected>
<option value="<tag:unselected.v />"><tag:unselected.l /></option>
</loop:unselected>
+</if:unselected>
</select>
</td>
<td>
<label for="selected_sources" class="hidden"><tag:selectlabel /></label>
<select name="selected_sources" multiple="multiple" size="5" id="selected_sources">
<option class="control" disabled="disabled" value=""><tag:selectlabel /></option>
+<if:selected>
<loop:selected>
<option value="<tag:selected.v />"><tag:selected.l /></option>
</loop:selected>
+</if:selected>
</select>
</td>
<td>