Index: typo3/sysext/opendocs/class.tx_opendocs.php
===================================================================
--- typo3/sysext/opendocs/class.tx_opendocs.php	(revision 0)
+++ typo3/sysext/opendocs/class.tx_opendocs.php	(revision 3036)
@@ -0,0 +1,195 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008 Benjamin Mack <mack@xnos.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+	// load the language file
+$GLOBALS['LANG']->includeLLFile('EXT:opendocs/locallang_opendocs.xml');
+
+require_once(PATH_typo3.'interfaces/interface.backend_toolbaritem.php');
+
+
+/**
+ * Adding a list of all open documents of a user to the backend.php
+ *
+ * @author	Benjamin Mack <mack@xnos.org>
+ * @package	TYPO3
+ * @subpackage	opendocs
+ */
+class tx_opendocs implements backend_toolbarItem {
+
+	/**
+	 * reference back to the backend object
+	 *
+	 * @var	TYPO3backend
+	 */
+	private $backendReference;
+	private $openDocs;
+	private $recentDocs;
+	private $EXTKEY = 'opendocs';
+
+
+	/**
+	 * constructor, loads the documents from the user control
+	 *
+	 * @return	void
+	 */
+	public function __construct() {
+		global $BE_USER;
+
+		list($this->openDocs,) = $BE_USER->getModuleData('alt_doc.php','ses');
+		$this->recentDocs = $BE_USER->getModuleData('opendocs::recent');
+	}
+
+
+	/**
+	 * sets the backend reference
+	 *
+	 * @param	TYPO3backend	backend object reference
+	 * @return	void
+	 */
+	public function setBackend(&$backendReference) {
+		$this->backendReference = $backendReference;
+	}
+
+
+	/**
+	 * renders the toolbar item and the empty menu
+	 *
+	 * @return	void
+	 */
+	public function render() {
+
+		$this->addJavascriptToBackend();
+		$this->addCssToBackend();
+
+			// return the toolbar item and an empty UL
+		$output  = '<a href="#" class="toolbar-item">';
+		$output .= '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], t3lib_extMgm::extRelPath($this->EXTKEY).'opendocs.png', 'width="23" height="14"').' title="'.$GLOBALS['LANG']->getLL('toolbaritem',1).'" alt="" />';
+		$output .= '</a>';
+		$output .= '<ul class="toolbar-item-menu" style="display: none;"></ul>';
+		return $output;
+	}
+
+
+	/**
+	 * returns the opened documents list as an array
+	 *
+	 * @return	array	all open documents as list-items
+	 */
+	public function getOpenDocuments() {
+		$docs = array();
+
+			// Traverse the list of open documents:
+		if (is_array($this->openDocs)) {	
+			foreach($this->openDocs as $md5k => $lnk) {
+				$docs[] = '<li><a target="content" href="'.htmlspecialchars('alt_doc.php?'.$lnk[2]).'">'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($lnk[0]))).'</a></li>';
+			}
+		}
+		return $docs;
+	}
+
+
+	/**
+	 * returns the recent documents list as an array
+	 *
+	 * @return	array	all recent documents as list-items
+	 */
+	public function getRecentDocuments() {
+		$docs = array();
+
+		if (is_array($this->recentDocs)) {
+			$docs[] = '<li class="menu-item-div">'.$GLOBALS['LANG']->getLL('recent_docs',1).'</li>';
+
+				// Traverse the list of open documents:
+			foreach($this->recentDocs as $md5k => $lnk) {
+				$docs[] = '<li><a target="content" href="'.htmlspecialchars('alt_doc.php?'.$lnk[2]).'">'.htmlspecialchars(strip_tags(t3lib_div::htmlspecialchars_decode($lnk[0]))).'</a></li>';
+			}
+		}
+		return $docs;
+	}
+
+
+
+	/**
+	 * returns additional attributes for the list item in the toolbar
+	 *
+	 * @return	string		list item HTML attibutes
+	 */
+	public function getAdditionalAttributes() {
+		return ' id="open-documents-menu"';
+	}
+
+
+	/**
+	 * adds the neccessary javascript to the backend
+	 *
+	 * @return	void
+	 */
+	private function addJavascriptToBackend() {
+		$this->backendReference->addJavascriptFile(t3lib_extMgm::extRelPath($this->EXTKEY).'opendocs.js');
+	}
+
+
+	/**
+	 * adds the neccessary CSS to the backend
+	 *
+	 * @return	void
+	 */
+	private function addCssToBackend() {
+		$this->backendReference->addCssFile('opendocs', t3lib_extMgm::extRelPath($this->EXTKEY).'opendocs.css');
+	}
+
+
+
+
+	/**
+	 * returns the opened documents list for the AJAX call formatted as HTML list
+	 *
+	 * @return	string		list item HTML attibutes
+	 */
+	public function renderBackendMenuContents($params, &$ajaxObj) {
+		$itms = $this->getOpenDocuments();
+		$itmsRecent = $this->getRecentDocuments();
+
+
+			// if there are "recent documents" in the list, add them 
+		if (count($itmsRecent)) {
+			$itms = array_merge($itms, $itmsRecent);
+		}
+
+
+		if (count($itms)) {
+			$ajaxObj->addContent('opendocs', implode('', $itms));
+		} else {
+			$ajaxObj->addContent('opendocs', '<li>'.$GLOBALS['LANG']->getLL('no_docs',1).'</li>');
+		}
+	}
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['EXT:opendocs/class.tx_opendocs.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['EXT:opendocs/class.tx_opendocs.php']);
+}
+?>
Index: typo3/sysext/opendocs/ext_tables.php
===================================================================
--- typo3/sysext/opendocs/ext_tables.php	(revision 3035)
+++ typo3/sysext/opendocs/ext_tables.php	(working copy)
@@ -1,7 +1,21 @@
 <?php
-if (!defined ('TYPO3_MODE')) 	die ('Access denied.');
+if (!defined('TYPO3_MODE')) 	die('Access denied.');
 
-if (TYPO3_MODE=='BE')	{
-	t3lib_extMgm::addModule('user','doc','after:ws',t3lib_extMgm::extPath($_EXTKEY).'mod/');
+
+if (TYPO3_MODE == 'BE') {
+
+		// register top module
+	$GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendItems'][] = t3lib_extMgm::extPath('opendocs').'registerToolbarItem.php';
+
+
+		// register AJAX call
+	$GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX']['tx_opendocs::backendmenu'] = t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php:tx_opendocs->renderBackendMenuContents';
+
+
+		// register menu module if option is wanted
+	$_EXTCONF = unserialize($_EXTCONF);
+	if ($_EXTCONF['enableModule']) {
+		t3lib_extMgm::addModule('user', 'doc', 'after:ws', t3lib_extMgm::extPath($_EXTKEY).'mod/');
+	}
 }
 ?>
Index: typo3/sysext/opendocs/opendocs.css
===================================================================
--- typo3/sysext/opendocs/opendocs.css	(revision 0)
+++ typo3/sysext/opendocs/opendocs.css	(revision 3036)
@@ -0,0 +1,49 @@
+#open-documents-menu {
+	width: 30px;
+}
+
+#open-documents-menu img {
+	margin: 1px 0 0;
+}
+
+#open-documents-menu ul {
+	width: 185px;
+	position: absolute;
+	list-style: none;
+	padding: 2px 0px 0px;
+	margin: 0px;
+	background-color: #f9f9f9;
+	border: 1px solid #abb2bc;
+	border-top: none;
+}
+
+#open-documents-menu li {
+	text-align: left;
+	float: none;
+	vertical-align: middle;
+	line-height: 14px;
+	font-size: 11px;
+	padding: 1px 1px 1px 0;
+}
+
+#open-documents-menu li img {
+	float: left;
+	padding-right: 3px;
+}
+
+#open-documents-menu li a {
+	text-decoration: none;
+	vertical-align: middle;
+	display: block;
+	padding: 1px 1px 1px 4px;
+	font-size: 11px;
+}
+
+#open-documents-menu li a:hover {
+	background: #f0f0f0;
+}
+#open-documents-menu li.menu-item-div {
+	border-top: 1px solid #abb2bc;
+	font-weight: bold;
+	padding: 2px 0 2px 3px;
+}
Index: typo3/sysext/opendocs/opendocs.js
===================================================================
--- typo3/sysext/opendocs/opendocs.js	(revision 0)
+++ typo3/sysext/opendocs/opendocs.js	(revision 3036)
@@ -0,0 +1,111 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2008 Benjamin Mack <mack@xnos.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * class to handle the open documents menu, loads the open documents dynamically
+ */
+var OpenDocs = Class.create({
+	ajaxScript: 'ajax.php',
+	ajaxID: 'tx_opendocs::backendmenu',
+	menuItem: 'open-documents-menu',
+	menu: null,		// the <ul> tag
+	toolbarItem: null,	// the <a> tag
+
+
+	/**
+	 * registers for resize event listener and executes on DOM ready
+	 */
+	initialize: function() {
+		Event.observe(window, 'load', function() {
+			this.getMenu();
+			Event.observe(window,        'resize', this.positionMenu.bindAsEventListener(this));
+			Event.observe(this.menuItem, 'click',    this.toggleMenu.bindAsEventListener(this));
+		}.bindAsEventListener(this));
+	},
+
+
+	getMenu: function() {
+		this.menu = $$('#' + this.menuItem + ' ul')[0];
+		this.toolbarItem = $$('#'+this.menuItem+' a')[0];
+	},
+
+
+	/**
+	 * positions the menu below the toolbar icon
+	 */
+	positionMenu: function() {
+		var calculatedOffset = 0;
+		var ownWidth         = this.menu.getWidth();
+		var parentWidth      = $(this.menuItem).getWidth();
+		var parentSiblings   = $(this.menuItem).previousSiblings();
+
+		parentSiblings.each(function(toolbarItem) {
+			calculatedOffset += toolbarItem.getWidth()-1;
+		});
+		calculatedOffset = calculatedOffset - ownWidth + parentWidth;
+		this.menu.setStyle({ left: calculatedOffset-2 + 'px' });
+	},
+
+
+	/**
+	 * toggles the visibility of the menu and places it under the toolbar icon
+	 */
+	toggleMenu: function() {
+		this.toolbarItem.blur();
+		if(!this.toolbarItem.hasClassName('toolbar-item-active')) {
+			this.showMenu();
+		} else {
+			this.hideMenu();
+		}
+	},
+
+
+	/**
+	 * displays the menu and does the AJAX call to the TYPO3 backend
+	 */
+	showMenu: function() {
+		new Ajax.Request(this.ajaxScript, {
+			parameters: 'ajaxID=' + this.ajaxID,
+			onSuccess: function(xhr) {
+				this.menu.innerHTML = xhr.responseText;
+				Effect.Appear(this.menu, {duration: 0.2});
+			}.bind(this)
+		});
+		this.positionMenu();
+		this.toolbarItem.addClassName('toolbar-item-active');
+		TYPO3BackendToolbarManager.hideOthers(this.toolbarItem);
+	},
+
+
+	/**
+	 * hides the menu
+	 */
+	hideMenu: function() {
+		Effect.Fade(this.menu, {duration: 0.1});
+		this.toolbarItem.removeClassName('toolbar-item-active');
+	}
+});
+
+var TYPO3BackendOpenDocs = new OpenDocs();
Index: typo3/sysext/opendocs/locallang_opendocs.xml
===================================================================
--- typo3/sysext/opendocs/locallang_opendocs.xml	(revision 0)
+++ typo3/sysext/opendocs/locallang_opendocs.xml	(revision 3036)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+	<meta type="array">
+		<description>Standard Document Module labels</description>
+		<type>module</type>
+		<fileId>EXT:opendocs/locallang_opendocs.xml</fileId>
+		<labelContext type="array">
+		</labelContext>
+	</meta>
+	<data type="array">
+		<languageKey index="default" type="array">
+			<label index="toolbaritem">Open and Recently Edited Documents</label>
+			<label index="open_docs">Opened Documents</label>
+			<label index="recent_docs">Recently Edited Documents</label>
+			<label index="no_docs">There are no open documents</label>
+		</languageKey>
+	</data>
+</T3locallang>

Property changes on: typo3/sysext/opendocs/locallang_opendocs.xml
___________________________________________________________________
Name: svn:executable
   + *

Index: typo3/sysext/opendocs/registerToolbarItem.php
===================================================================
--- typo3/sysext/opendocs/registerToolbarItem.php	(revision 0)
+++ typo3/sysext/opendocs/registerToolbarItem.php	(revision 3036)
@@ -0,0 +1,14 @@
+<?php
+
+if (!defined ('TYPO3_MODE')) 	die ('Access denied.');
+
+if(TYPO3_MODE=='BE') {
+
+		// first include the class file
+	include(t3lib_extMgm::extPath('opendocs').'class.tx_opendocs.php');
+
+		// now register the class as toolbar item
+	$GLOBALS['TYPO3backend']->addToolbarItem('opendocs', 'tx_opendocs');
+}
+
+?>
Index: typo3/sysext/opendocs/ext_emconf.php
===================================================================
--- typo3/sysext/opendocs/ext_emconf.php	(revision 3035)
+++ typo3/sysext/opendocs/ext_emconf.php	(working copy)
@@ -25,7 +25,7 @@
 	'uploadfolder' => 0,
 	'createDirs' => '',
 	'modify_tables' => '',
-	'clearCacheOnLoad' => 0,
+	'clearCacheOnLoad' => 1,
 	'lockType' => '',
 	'author' => 'Benjamin Mack',
 	'author_email' => 'mack@xnos.org',
@@ -48,4 +48,4 @@
 	),
 );
 
-?>
\ No newline at end of file
+?>
Index: typo3/sysext/opendocs/opendocs.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: typo3/sysext/opendocs/opendocs.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: typo3/sysext/opendocs/ext_conf_template.txt
===================================================================
--- typo3/sysext/opendocs/ext_conf_template.txt	(revision 0)
+++ typo3/sysext/opendocs/ext_conf_template.txt	(revision 3036)
@@ -0,0 +1,2 @@
+  # cat=basic/enable; type=boolean; label=Enable Open Documents module: Enables, additionally to the menu in the top bar the old module "Open Documents" / "Doc" in the module menu as a submodule of User.
+enableModule = 0

Property changes on: typo3/sysext/opendocs/ext_conf_template.txt
___________________________________________________________________
Name: svn:executable
   + *

Index: typo3/alt_doc.php
===================================================================
--- typo3/alt_doc.php	(revision 3035)
+++ typo3/alt_doc.php	(working copy)
@@ -1453,13 +1453,32 @@
 	function closeDocument($code=0)	{
 		global $BE_USER;
 
-			// If current document is found in docHandler, then unset it, possibly unset it ALL and finally, write it to the session data:
-		if (isset($this->docHandler[$this->storeUrlMd5]))	{
+			// If current document is found in docHandler, 
+			// then unset it, possibly unset it ALL and finally, write it to the session data
+		if (isset($this->docHandler[$this->storeUrlMd5])) {
+
+				// add the closing document to the recent documents
+			$recentDocs = $BE_USER->getModuleData('opendocs::recent');
+			if (!is_array($recentDocs)) {
+				$recentDocs = array();
+			}
+			$closedDoc = $this->docHandler[$this->storeUrlMd5];
+			$recentDocs = array_merge(array($this->storeUrlMd5 => $closedDoc), $recentDocs);
+			if (count($recentDocs) > 8) {
+				$recentDocs = array_slice($recentDocs, 0, 8);
+			}
+
+				// remove it from the list of the open documents
 			unset($this->docHandler[$this->storeUrlMd5]);
-			if ($code=='3')	$this->docHandler=array();
-			$BE_USER->pushModuleData('alt_doc.php',array($this->docHandler,$this->docDat[1]));
+			if ($code == '3') {
+				$recentDocs = array_merge($this->docHandler, $recentDocs);
+				$this->docHandler = array();
+			}
+			$BE_USER->pushModuleData('opendocs::recent', $recentDocs);
+			$BE_USER->pushModuleData('alt_doc.php', array($this->docHandler, $this->docDat[1]));
 		}
 
+
 			// If ->returnEditConf is set, then add the current content of editconf to the ->retUrl variable: (used by other scripts, like wizard_add, to know which records was created or so...)
 		if ($this->returnEditConf && $this->retUrl!='dummy.php')	{
 			$this->retUrl.='&returnEditConf='.rawurlencode(serialize($this->editconf));
