Changeset b62c486 in github
- Timestamp:
- May 2, 2010 11:09:36 AM (3 years ago)
- Branches:
- master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
- Children:
- e095094
- Parents:
- d44571b
- Files:
-
- 5 edited
-
CHANGELOG (modified) (1 diff)
-
program/js/app.js (modified) (6 diffs)
-
program/js/list.js (modified) (11 diffs)
-
program/steps/mail/func.inc (modified) (4 diffs)
-
program/steps/mail/list.inc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
CHANGELOG
rea50e71 rb62c486 2 2 =========================== 3 3 4 - Allow columns order change per user - drag&drop (#1485795) 4 5 - Add References header in read receipt (#1486681) 5 6 - Fix database constraint violation when opening a message (#1486696) -
program/js/app.js
rcecf46a4 rb62c486 167 167 168 168 this.message_list = new rcube_list_widget(this.gui_objects.messagelist, 169 {multiselect:true, multiexpand:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time}); 169 {multiselect:true, multiexpand:true, draggable:true, keyboard:true, 170 column_movable:this.env.col_movable, column_fixed:0, dblclick_time:this.dblclick_time}); 170 171 this.message_list.row_init = function(o){ p.init_message_row(o); }; 171 172 this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); }); … … 177 178 this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); }); 178 179 this.message_list.addEventListener('expandcollapse', function(e){ p.msglist_expand(e); }); 180 this.message_list.addEventListener('column_replace', function(e){ p.msglist_set_coltypes(e); }); 179 181 180 182 document.onmouseup = function(e){ return p.doc_mouse_up(e); }; 181 183 this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); }; 182 184 183 this.set_message_coltypes(this.env.coltypes);184 185 this.message_list.init(); 185 186 this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', true); … … 1488 1489 this.env.messages[row.uid].expanded = row.expanded; 1489 1490 }; 1491 1492 this.msglist_set_coltypes = function(list) 1493 { 1494 var i, found, name, cols = list.list.tHead.rows[0].cells; 1495 1496 this.env.coltypes = []; 1497 1498 for (i=0; i<cols.length; i++) 1499 if (cols[i].id && cols[i].id.match(/^rcm/)) { 1500 name = cols[i].id.replace(/^rcm/, ''); 1501 this.env.coltypes[this.env.coltypes.length] = name == 'to' ? 'from' : name; 1502 } 1503 1504 if ((found = $.inArray('flag', this.env.coltypes)) >= 0) 1505 this.set_env('flagged_col', found); 1506 1507 this.http_post('save-pref', { '_name':'list_cols', '_value':this.env.coltypes }); 1508 }; 1490 1509 1491 1510 this.check_droptarget = function(id) … … 1693 1712 var update, add_url = ''; 1694 1713 1714 if (!sort_col) sort_col = this.env.sort_col; 1715 if (!sort_order) sort_order = this.env.sort_order; 1716 1695 1717 if (this.env.sort_col != sort_col || this.env.sort_order != sort_order) { 1696 1718 update = 1; … … 1703 1725 } 1704 1726 1705 if (cols.join() != this.env.coltypes.join()) { 1706 update = 1; 1707 add_url += '&_cols=' + cols.join(','); 1727 if (cols && cols.length) { 1728 // make sure new columns are added at the end of the list 1729 var i, idx, name, newcols = [], oldcols = this.env.coltypes; 1730 for (i=0; i<oldcols.length; i++) { 1731 name = oldcols[i] == 'to' ? 'from' : oldcols[i]; 1732 idx = $.inArray(name, cols); 1733 if (idx != -1) { 1734 newcols[newcols.length] = name; 1735 delete cols[idx]; 1736 } 1737 } 1738 for (i=0; i<cols.length; i++) 1739 if (cols[i]) 1740 newcols[newcols.length] = cols[i]; 1741 1742 if (newcols.join() != this.env.coltypes.join()) { 1743 update = 1; 1744 add_url += '&_cols=' + newcols.join(','); 1745 } 1708 1746 } 1709 1747 … … 4440 4478 4441 4479 var found; 4442 if ((found = $.inArray('subject', this.env.coltypes)) >= 0) {4480 if ((found = $.inArray('subject', this.env.coltypes)) >= 0) { 4443 4481 this.set_env('subject_col', found); 4444 4482 if (this.message_list) 4445 4483 this.message_list.subject_col = found+1; 4446 4484 } 4447 if ((found = $.inArray('flag', this.env.coltypes)) >= 0)4485 if ((found = $.inArray('flag', this.env.coltypes)) >= 0) 4448 4486 this.set_env('flagged_col', found); 4487 4488 this.message_list.init_header(); 4449 4489 }; 4450 4490 -
program/js/list.js
rdd51b73 rb62c486 34 34 this.selection = []; 35 35 this.rowcount = 0; 36 this.colcount = 0; 36 37 37 38 this.subject_col = -1; … … 41 42 this.multi_selecting = false; 42 43 this.draggable = false; 44 this.column_movable = false; 43 45 this.keyboard = false; 44 46 this.toggleselect = false; … … 46 48 this.dont_select = false; 47 49 this.drag_active = false; 50 this.col_drag_active = false; 51 this.column_fixed = null; 48 52 this.last_selected = 0; 49 53 this.shift_start = 0; … … 73 77 this.rowcount = 0; 74 78 75 var row; 76 for(var r=0; r<this.list.tBodies[0].childNodes.length; r++) { 77 row = this.list.tBodies[0].childNodes[r]; 78 while (row && row.nodeType != 1) { 79 row = row.nextSibling; 80 r++; 81 } 82 79 var row, r; 80 81 for (r=0; r<this.list.tBodies[0].rows.length; r++) { 82 row = this.list.tBodies[0].rows[r]; 83 83 this.init_row(row); 84 84 this.rowcount++; 85 85 } 86 86 87 this.init_header(); 87 88 this.frame = this.list.parentNode; 88 89 … … 121 122 122 123 /** 124 * Init list column headers and set mouse events on them 125 */ 126 init_header: function() 127 { 128 if (this.list && this.list.tHead) { 129 this.colcount = 0; 130 131 var col, r, p = this; 132 // add events for list columns moving 133 if (this.column_movable && this.list.tHead && this.list.tHead.rows) { 134 for (r=0; r<this.list.tHead.rows[0].cells.length; r++) { 135 if (this.column_fixed == r) 136 continue; 137 col = this.list.tHead.rows[0].cells[r]; 138 col.onmousedown = function(e){ return p.drag_column(e, this); }; 139 this.colcount++; 140 } 141 } 142 } 143 }, 144 145 146 /** 123 147 * Remove all list rows 124 148 */ … … 208 232 209 233 /** 234 * onmousedown-handler of message list column 235 */ 236 drag_column: function(e, col) 237 { 238 if (this.colcount > 1) { 239 this.drag_start = true; 240 this.drag_mouse_start = rcube_event.get_mouse_pos(e); 241 242 rcube_event.add_listener({event:'mousemove', object:this, method:'column_drag_mouse_move'}); 243 rcube_event.add_listener({event:'mouseup', object:this, method:'column_drag_mouse_up'}); 244 245 // enable dragging over iframes 246 this.add_dragfix(); 247 248 // find selected column number 249 for (var i=0; i<this.list.tHead.rows[0].cells.length; i++) { 250 if (col == this.list.tHead.rows[0].cells[i]) { 251 this.selected_column = i; 252 break; 253 } 254 } 255 } 256 257 return false; 258 }, 259 260 261 /** 210 262 * onmousedown-handler of message list row 211 263 */ … … 237 289 238 290 // enable dragging over iframes 239 $('iframe').each(function() { 240 $('<div class="iframe-dragdrop-fix"></div>') 241 .css({background: '#fff', 242 width: this.offsetWidth+'px', height: this.offsetHeight+'px', 243 position: 'absolute', opacity: '0.001', zIndex: 1000 244 }) 245 .css($(this).offset()) 246 .appendTo('body'); 247 }); 291 this.add_dragfix(); 248 292 } 249 293 … … 288 332 if (!this.drag_active) { 289 333 // remove temp divs 290 $('div.iframe-dragdrop-fix').each(function() { this.parentNode.removeChild(this); });334 this.del_dragfix(); 291 335 rcube_event.cancel(e); 292 336 } … … 932 976 case 27: 933 977 if (this.drag_active) 934 return this.drag_mouse_up(e); 978 return this.drag_mouse_up(e); 979 if (this.col_drag_active) { 980 this.selected_column = null; 981 return this.column_drag_mouse_up(e); 982 } 935 983 936 984 case 40: … … 1041 1089 1042 1090 if (!this.draglayer) 1043 this.draglayer = $('<div>').attr('id', 'rcmdraglayer').css({ position:'absolute', display:'none', 'z-index':2000 }).appendTo(document.body); 1091 this.draglayer = $('<div>').attr('id', 'rcmdraglayer') 1092 .css({ position:'absolute', display:'none', 'z-index':2000 }) 1093 .appendTo(document.body); 1044 1094 1045 1095 // also select childs of (collapsed) threads for dragging … … 1135 1185 1136 1186 // remove temp divs 1187 this.del_dragfix(); 1188 1189 this.triggerEvent('dragend'); 1190 1191 return rcube_event.cancel(e); 1192 }, 1193 1194 1195 /** 1196 * Handler for mouse move events for dragging list column 1197 */ 1198 column_drag_mouse_move: function(e) 1199 { 1200 if (this.drag_start) { 1201 // check mouse movement, of less than 3 pixels, don't start dragging 1202 var i, m = rcube_event.get_mouse_pos(e); 1203 1204 if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3)) 1205 return false; 1206 1207 if (!this.col_draglayer) { 1208 var lpos = $(this.list).offset(), 1209 cells = this.list.tHead.rows[0].cells; 1210 1211 // create dragging layer 1212 this.col_draglayer = $('<div>').attr('id', 'rcmcoldraglayer') 1213 .css(lpos).css({ position:'absolute', 'z-index':2001, 1214 'background-color':'white', opacity:0.75, 1215 height: (this.frame.offsetHeight-2)+'px', width: (this.frame.offsetWidth-2)+'px' }) 1216 .appendTo(document.body) 1217 // ... and column position indicator 1218 .append($('<div>').attr('id', 'rcmcolumnindicator') 1219 .css({ position:'absolute', 'border-right':'2px dotted #555', 1220 'z-index':2002, height: (this.frame.offsetHeight-2)+'px' })); 1221 1222 this.cols = []; 1223 this.list_pos = this.list_min_pos = lpos.left; 1224 // save columns positions 1225 for (i=0; i<cells.length; i++) { 1226 this.cols[i] = cells[i].offsetWidth; 1227 if (this.column_fixed !== null && i <= this.column_fixed) { 1228 this.list_min_pos += this.cols[i]; 1229 } 1230 } 1231 } 1232 1233 this.col_draglayer.show(); 1234 this.col_drag_active = true; 1235 this.triggerEvent('column_dragstart'); 1236 } 1237 1238 // set column indicator position 1239 if (this.col_drag_active && this.col_draglayer) { 1240 var i, cpos = 0, pos = rcube_event.get_mouse_pos(e); 1241 1242 for (i=0; i<this.cols.length; i++) { 1243 if (pos.x >= this.cols[i]/2 + this.list_pos + cpos) 1244 cpos += this.cols[i]; 1245 else 1246 break; 1247 } 1248 1249 // handle fixed columns on left 1250 if (i == 0 && this.list_min_pos > pos.x) 1251 cpos = this.list_min_pos - this.list_pos; 1252 // empty list needs some assignment 1253 else if (!this.list.rowcount && i == this.cols.length) 1254 cpos -= 2; 1255 $('#rcmcolumnindicator').css({ width: cpos+'px'}); 1256 this.triggerEvent('column_dragmove', e?e:window.event); 1257 } 1258 1259 this.drag_start = false; 1260 1261 return false; 1262 }, 1263 1264 1265 /** 1266 * Handler for mouse up events for dragging list columns 1267 */ 1268 column_drag_mouse_up: function(e) 1269 { 1270 document.onmousemove = null; 1271 1272 if (this.col_draglayer) { 1273 (this.col_draglayer).remove(); 1274 this.col_draglayer = null; 1275 } 1276 1277 if (this.col_drag_active) 1278 this.focus(); 1279 this.col_drag_active = false; 1280 1281 rcube_event.remove_listener({event:'mousemove', object:this, method:'column_drag_mouse_move'}); 1282 rcube_event.remove_listener({event:'mouseup', object:this, method:'column_drag_mouse_up'}); 1283 // remove temp divs 1284 this.del_dragfix(); 1285 1286 if (this.selected_column !== null && this.cols && this.cols.length) { 1287 var i, cpos = 0, pos = rcube_event.get_mouse_pos(e); 1288 1289 // find destination position 1290 for (i=0; i<this.cols.length; i++) { 1291 if (pos.x >= this.cols[i]/2 + this.list_pos + cpos) 1292 cpos += this.cols[i]; 1293 else 1294 break; 1295 } 1296 1297 if (i != this.selected_column && i != this.selected_column+1) { 1298 this.column_replace(this.selected_column, i); 1299 } 1300 } 1301 1302 this.triggerEvent('column_dragend'); 1303 1304 return rcube_event.cancel(e); 1305 }, 1306 1307 1308 /** 1309 * Creates a layer for drag&drop over iframes 1310 */ 1311 add_dragfix: function() 1312 { 1313 $('iframe').each(function() { 1314 $('<div class="iframe-dragdrop-fix"></div>') 1315 .css({background: '#fff', 1316 width: this.offsetWidth+'px', height: this.offsetHeight+'px', 1317 position: 'absolute', opacity: '0.001', zIndex: 1000 1318 }) 1319 .css($(this).offset()) 1320 .appendTo(document.body); 1321 }); 1322 }, 1323 1324 1325 /** 1326 * Removes the layer for drag&drop over iframes 1327 */ 1328 del_dragfix: function() 1329 { 1137 1330 $('div.iframe-dragdrop-fix').each(function() { this.parentNode.removeChild(this); }); 1138 1139 this.triggerEvent('dragend'); 1140 1141 return rcube_event.cancel(e); 1331 }, 1332 1333 1334 /** 1335 * Replaces two columns 1336 */ 1337 column_replace: function(from, to) 1338 { 1339 var cells = this.list.tHead.rows[0].cells, 1340 elem = cells[from], 1341 before = cells[to], 1342 td = document.createElement('td'); 1343 1344 // replace header cells 1345 if (before) 1346 cells[0].parentNode.insertBefore(td, before); 1347 else 1348 cells[0].parentNode.appendChild(td); 1349 cells[0].parentNode.replaceChild(elem, td); 1350 1351 // replace list cells 1352 for (r=0; r<this.list.tBodies[0].rows.length; r++) { 1353 row = this.list.tBodies[0].rows[r]; 1354 1355 elem = row.cells[from]; 1356 before = row.cells[to]; 1357 td = document.createElement('td'); 1358 1359 if (before) 1360 row.insertBefore(td, before); 1361 else 1362 row.appendChild(td); 1363 row.replaceChild(elem, td); 1364 } 1365 1366 // update subject column position 1367 if (this.subject_col == from) 1368 this.subject_col = to > from ? to - 1 : to; 1369 1370 this.triggerEvent('column_replace'); 1142 1371 }, 1143 1372 -
program/steps/mail/func.inc
rea50e71 rb62c486 155 155 156 156 // define list of cols to be displayed based on parameter or config 157 if (empty($attrib['columns'])) 158 $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); 159 else 160 $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns'])); 157 if (empty($attrib['columns'])) { 158 $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); 159 $OUTPUT->set_env('col_movable', !in_array('list_cols', (array)$CONFIG['dont_override'])); 160 } 161 else { 162 $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns'])); 163 $attrib['columns'] = $a_show_cols; 164 } 161 165 162 166 // save some variables for use in ajax list 163 $_SESSION['list_columns'] = $a_show_cols;164 167 $_SESSION['list_attrib'] = $attrib; 165 168 … … 221 224 html::tag('thead', null, html::tag('tr', null, $thead)) . 222 225 html::tag('tbody', null, ''), 223 array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));226 array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary')); 224 227 } 225 228 … … 233 236 global $CONFIG, $IMAP, $OUTPUT; 234 237 235 if (empty($_SESSION['list_columns'])) 238 if (!empty($_SESSION['list_attrib']['columns'])) 239 $a_show_cols = $_SESSION['list_attrib']['columns']; 240 else 236 241 $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); 237 else238 $a_show_cols = $_SESSION['list_columns'];239 242 240 243 $mbox = $IMAP->get_mailbox_name(); … … 325 328 if ($browser->ie && $replace) 326 329 $OUTPUT->command('offline_message_list', false); 327 }330 } 328 331 329 332 -
program/steps/mail/list.inc
rf52c936f rb62c486 46 46 { 47 47 $save_arr = array(); 48 $ _SESSION['list_columns'] = $save_arr['list_cols'] = explode(',', $cols);48 $save_arr['list_cols'] = explode(',', $cols); 49 49 } 50 50
Note: See TracChangeset
for help on using the changeset viewer.
