* Stylite template got an application header again

and other bugfixes for the tab restore: commits r1436-44
This commit is contained in:
Ralf Becker 2010-11-21 13:35:12 +00:00
parent 4a17a747f0
commit 095567423d
5 changed files with 247 additions and 47 deletions

View File

@ -489,3 +489,18 @@ body {
.egw_fw_content_browser_iframe {
}
.egw_fw_ui_app_header_container {
border-width: 0px 1px 0px 1px;
border-style: solid;
border-color: #D5DDE6;
}
.egw_fw_ui_app_header {
border-width: 0px 0px 1px 0px;
border-style: solid;
border-color: #D5DDE6;
padding: 5px 2px 4px 15px;
font-size: 9pt;
font-weight: bold;
}

View File

@ -142,6 +142,11 @@ class jdots_framework extends egw_framework
{
return $matches[1];
}
if (strlen($GLOBALS['egw_info']['server']['webserver_url']) > 1)
{
list(,$url) = explode(parse_url($GLOBALS['egw_info']['server']['webserver_url'],PHP_URL_PATH),
parse_url($url,PHP_URL_PATH),2);
}
if (preg_match('/\/([^\/]+)\/([^\/]+\.php)?(\?|\/|$)/',$url,$matches))
{
return $matches[1];
@ -273,7 +278,7 @@ class jdots_framework extends egw_framework
if (typeof window.parent.framework != "undefined")
{
var app = window.parent.framework.getApplicationByName("'.$app.'");
window.parent.framework.setWebsiteTitle(app,"'.htmlspecialchars($vars['website_title']).'");
window.parent.framework.setWebsiteTitle(app,"'.htmlspecialchars($vars['website_title']).'","'.$app_header.'");
}';
//Register the global key press handler
@ -723,8 +728,10 @@ class jdots_framework extends egw_framework
/**
* Stores the user defined sorting of the applications inside the preferences
*/
public function ajax_appsort($apps)
*
* @param array $apps
*/
public function ajax_appsort(array $apps)
{
$order = array();
$i = 0;
@ -749,6 +756,10 @@ class jdots_framework extends egw_framework
/**
* Prepare an array with apps used to render the navbar
*
* @param string $url contains the current url on the client side. It is used to
* determine whether the default app/home should be opened on the client
* or whether a specific application-url has been given.
*
* @return array of array(
* 'name' => app / directory name
* 'title' => translated application title
@ -757,9 +768,12 @@ class jdots_framework extends egw_framework
* 'icon_app' => application of icon
* 'icon_hover' => hover-icon, if used by template
* 'target'=> ' target="..."' attribute fragment to open url in target, popup or ''
* 'opened' => unset or false if the tab should not be opened, otherwise the numeric position in the tab list
* 'active' => true if this tab should be the active one when it is restored, otherwise unset or false
* 'openOnce' => unset or the url which will be opened when the tab is restored
* )
*/
public function ajax_navbar_apps()
public function ajax_navbar_apps($url)
{
$apps = parent::_get_navbar_apps();
@ -781,13 +795,43 @@ class jdots_framework extends egw_framework
unset($apps['sitemgr-link']);
}
// check if user called a specific url --> open it as active tab
$last_direct_url =& egw_cache::getSession(__CLASS__, 'last_direct_url');
if ($url !== $last_direct_url)
{
$active_tab = $url_tab = self::app_from_url($url);
$last_direct_url = $url;
}
if ($active_tab)
{
$apps[$active_tab]['openOnce'] = str_replace('&cd=yes','',$url);
$store_prefs = true;
}
else
{
$active_tab = $GLOBALS['egw_info']['user']['preferences']['common']['active_tab'];
}
$open_tabs = explode(',',$GLOBALS['egw_info']['user']['preferences']['common']['open_tabs']);
if (!in_array($active_tab,$open_tabs))
{
$open_tabs[] = $active_tab;
$store_prefs = true;
}
if ($store_prefs)
{
$GLOBALS['egw']->preferences->read_repository();
$GLOBALS['egw']->preferences->change('common', 'open_tabs', implode(',',$open_tabs));
$GLOBALS['egw']->preferences->change('common', 'active_tab', $active_tab);
$GLOBALS['egw']->preferences->save_repository(true);
}
//error_log(__METHOD__."('$url') url_tab='$url_tab', active_tab=$active_tab, open_tabs=".array2string($open_tabs));
// Restore Tabs
foreach(explode(',',$GLOBALS['egw_info']['user']['preferences']['common']['open_tabs']) as $n => $app)
foreach($open_tabs as $n => $app)
{
if (isset($apps[$app])) // user might no longer have app rights
{
$apps[$app]['opened'] = $n;
if ($GLOBALS['egw_info']['user']['preferences']['common']['active_tab'] == $app)
if ($app == $active_tab)
{
$apps[$app]['active'] = true;
}

View File

@ -194,7 +194,7 @@ egw_fw.prototype.setActiveApp = function(_app)
this.fw.setSidebox(this.app, data.data, data.md5);
this.app.sidemenuEntry.hideAjaxLoader();
}
}, {'app' : _app, 'fw' : this});
}, {'app' : _app, 'fw' : this});
}
}
else
@ -203,10 +203,7 @@ egw_fw.prototype.setActiveApp = function(_app)
}
//Set the website title
if (_app.website_title)
{
document.title = _app.website_title;
}
this.refreshAppTitle();
//Show the application tab
if (_app.tab)
@ -390,13 +387,17 @@ egw_fw.prototype.notifyTabChange = function()
/**
* Checks whether the application already owns a tab and creates one if it doesn't exist
*/
egw_fw.prototype.createApplicationTab = function(_app)
egw_fw.prototype.createApplicationTab = function(_app, _pos)
{
//Default the pos parameter to -1
if (typeof _pos == 'undefined')
_pos = -1;
if (_app.tab == null)
{
//Create the tab
_app.tab = this.tabsUi.addTab(_app.icon, this.tabClickCallback, this.tabCloseClickCallback,
_app);
_app, _pos);
_app.tab.setTitle(_app.displayName);
//Set the tab closeable if there's more than one tab
@ -412,10 +413,14 @@ egw_fw.prototype.createApplicationTab = function(_app)
* @param bool _hidden specifies, whether the application should be set active
* after opening the tab
*/
egw_fw.prototype.applicationTabNavigate = function(_app, _url, _useIframe, _hidden)
egw_fw.prototype.applicationTabNavigate = function(_app, _url, _useIframe, _hidden, _pos)
{
//Default the post parameter to -1
if (typeof _pos == 'undefined')
_pos = -1;
//Create the tab for that application
this.createApplicationTab(_app);
this.createApplicationTab(_app, _pos);
if (typeof _url == 'undefined' || _url == null)
_url = _app.indexUrl;
@ -442,7 +447,6 @@ egw_fw.prototype.applicationTabNavigate = function(_app, _url, _useIframe, _hidd
_app.browser.browse(_url, true);//_useIframe);
//
if (typeof _hidden == 'undefined' || !_hidden)
{
this.setActiveApp(_app);
@ -497,8 +501,17 @@ egw_fw.prototype.parseAppFromUrl = function(_url)
egw_fw.prototype.loadApplicationsCallback = function(apps)
{
var defaultApp = null;
var restore = [];
var activeTabIdx = 0;
var restore = new Object;
var restore_count = 0;
var mkRestoreEntry = function(_app, _pos, _url, _active) {
return {
'app': _app,
'position': _pos,
'url': _url,
'active': _active
}
}
//Iterate through the application array returned
for (var i = 0; i < apps.length; i++)
@ -531,34 +544,62 @@ egw_fw.prototype.loadApplicationsCallback = function(apps)
if ((typeof app.opened != 'undefined') && (app.opened !== false))
{
defaultApp = null;
restore[app.opened] = appData;
if (app.active)
activeTabIdx = app.opened;
var url = null;
if (typeof app.openOnce != 'undefined' && app.openOnce)
url = app.openOnce;
restore[appData.appName] = mkRestoreEntry(appData, app.opened,
url, app.active ? 1 : 0);
restore_count += 1;
}
this.applications[appData.appName] = appData;
}
// check if a menuaction or app is specified in the url --> display that
//Processing of the url or the defaultApp is now deactivated.
/* // check if a menuaction or app is specified in the url --> display that
var _app = this.parseAppFromUrl(window.location.href);
if (_app)
{
_url = window.location.href.replace(/&?cd=yes/,'');
this.applicationTabNavigate(_app, _url);
}
//If this app is already opened, don't change its position. Otherwise
//add it to the end of the tab list
var appPos = restore_count;
if (typeof restore[_app.appName] != 'undefined')
appPos = restore[_app.appName].position;
restore[_app.appName] = mkRestoreEntry(_app, appPos,
window.location.href.replace(/&?cd=yes/,''), 2);
}*/
// else display the default application
else if (defaultApp)
if (defaultApp && restore_count == 0)
{
this.applicationTabNavigate(defaultApp);
restore[defaultApp.appName] = mkRestoreEntry(defaultApp, 0, null, 1);
}
// restore the already opened tabs
if (restore.length > 0)
{
for (var i = 0; i < restore.length; i++)
//The last parameter is the so called "hidden" parameter
this.applicationTabNavigate(restore[i], null, null, i != activeTabIdx);
}
//Generate an array with all tabs which shall be restored sorted in by
//their active state
//Fill in the sorted_restore array...
var sorted_restore = [];
for (appName in restore)
sorted_restore[sorted_restore.length] = restore[appName];
//...and sort it
sorted_restore.sort(function (a, b) {
return ((a.active < b.active) ? 1 : ((a.active == b.active) ? 0 : -1));
});
//Now actually restore the tabs by passing the application, the url, whether
//this is an legacyApp (null triggers the application default), whether the
//application is hidden (only the active tab is shown) and its position
//in the tab list.
for (var i = 0; i < sorted_restore.length; i++)
this.applicationTabNavigate(
sorted_restore[i].app, sorted_restore[i].url, null, i != 0,
sorted_restore[i].position);
this.scrollAreaUi.update();
@ -581,7 +622,7 @@ egw_fw.prototype.loadApplications = function(_menuaction)
this.tabsUi.clean();
//Perform an AJAX request loading all available applications
var req = new egw_json_request(_menuaction)
var req = new egw_json_request(_menuaction, [window.location.href])
req.sendRequest(true, this.loadApplicationsCallback, this);
}
@ -714,10 +755,14 @@ egw_fw.prototype.setSidebox = function(_app, _data, _md5)
}
_app.hasSideboxMenuContent = true;
_app.sidemenuEntry.parent.open(_app.sidemenuEntry);
_app.parentFw.scrollAreaUi.update();
_app.parentFw.scrollAreaUi.setScrollPos(0);
//Only view the sidemenu content if this is really the active application
if (_app == _app.parentFw.activeApp)
{
_app.sidemenuEntry.parent.open(_app.sidemenuEntry);
_app.parentFw.scrollAreaUi.update();
_app.parentFw.scrollAreaUi.setScrollPos(0);
}
}
}
@ -726,10 +771,24 @@ egw_fw.prototype.setSidebox = function(_app, _data, _md5)
* @param object _app the application whose title should be set.
* @param string _title title to set
*/
egw_fw.prototype.setWebsiteTitle = function(_app,_title)
egw_fw.prototype.setWebsiteTitle = function(_app, _title, _header)
{
document.title = _title;
if (_app) _app.website_title = _title;
if (_app) {
_app.website_title = _title;
_app.app_header = _header;
if (_app == this.activeApp)
this.refreshAppTitle();
}
}
egw_fw.prototype.refreshAppTitle = function()
{
if (this.activeApp)
{
this.tabsUi.setAppHeader(this.activeApp.app_header);
document.title = this.activeApp.website_title;
}
}
/**

View File

@ -22,6 +22,9 @@ function egw_fw_class_application(_parentFw, _appName, _displayName, _icon,
this.legacyApp = _legacyApp;
this.hasPrerequisites;
this.website_title = '';
this.app_header = '';
this.sideboxWidth = _sideboxWidth;
//Setup a link to the parent framework class

View File

@ -359,9 +359,10 @@ egw_fw_ui_sidemenu.prototype.clean = function()
* @param function(_sender) _callback specifies the function which should be called when the tab title is clicked. The _sender parameter passed is a reference to this egw_fw_ui_tab element.
* @param function(_sender) _closeCallback specifies the function which should be called when the tab close button is clicked. The _sender parameter passed is a reference to this egw_fw_ui_tab element.
* @param object _tag can be used to attach any user data to the object. Inside egw_fw _tag is used to attach an egw_fw_class_application to each sidemenu entry.
* @param int _pos is the position where the tab will be inserted
*/
function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
_closeCallback, _tag)
_closeCallback, _tag, _pos)
{
this.parent = _parent;
this.contHeaderDiv = _contHeaderDiv;
@ -371,9 +372,11 @@ function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
this.closeable = true;
this.callback = _callback;
this.closeCallback = _closeCallback;
this.position = _pos;
//Create the header div and set its "click" function and "hover" event
this.headerDiv = document.createElement("span");
this.headerDiv._position = _pos;
$(this.headerDiv).addClass("egw_fw_ui_tab_header");
//Create a new callback object and attach it to the header div
@ -440,7 +443,31 @@ function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
$(this.contentDiv).addClass("egw_fw_ui_tab_content");
$(this.contentDiv).hide();
$(this.contHeaderDiv).append(this.headerDiv);
//Sort the element in at the given position
var _this = this;
var $_children = $(this.contHeaderDiv).children();
var _cnt = $_children.size();
if (_cnt > 0 && _pos > -1)
{
$_children.each(function(i) {
if (_pos <= this._position)
{
$(this).before(_this.headerDiv);
return false;
}
else if (i == (_cnt - 1))
{
$(this).after(_this.headerDiv);
return false;
}
});
}
else
{
$(this.contHeaderDiv).append(this.headerDiv);
}
$(this.contDiv).append(this.contentDiv);
}
@ -531,12 +558,40 @@ function egw_fw_ui_tabs(_contDiv)
$(this.contHeaderDiv).addClass("egw_fw_ui_tabs_header");
$(this.contDiv).append(this.contHeaderDiv);
this.appHeaderContainer = document.createElement("div");
$(this.appHeaderContainer).addClass("egw_fw_ui_app_header_container");
$(this.contDiv).append(this.appHeaderContainer);
this.appHeader = document.createElement("div");
$(this.appHeader).addClass("egw_fw_ui_app_header");
$(this.appHeader).hide();
$(this.appHeaderContainer).append(this.appHeader);
this.tabs = Array();
this.activeTab = null;
this.tabHistory = Array();
}
/**
* Sets the "appHeader" text below the tabs list.
*
* @param string _text is the text which will be seen in the appHeader.
*/
egw_fw_ui_tabs.prototype.setAppHeader = function(_text)
{
if (_text != "")
{
$(this.appHeader).empty();
$(this.appHeader).append("<span style=\"color:gray \">&raquo;</span> " + _text);
$(this.appHeader).show();
}
else
{
$(this.appHeader).hide();
}
}
/**
* Function internally used to remove double entries from the tab history. The tab
* history is used to store the order in which the tabs have been opened, to be able
@ -558,13 +613,37 @@ egw_fw_ui_tabs.prototype.cleanHistory = function()
* @param function _callback(_sender) function which should be called whenever the tab header is clicked. The _sender parameter passed is a reference to this egw_fw_ui_tab element.
* @param function _closeCallback(_sender) function which should be called whenever the close button of the tab is clicked. The _sender parameter passed is a reference to this egw_fw_ui_tab element.
* @param object _tag can be used to attach any user data to the object. Inside egw_fw _tag is used to attach an egw_fw_class_application to each sidemenu entry.
* @param int _pos specifies the position in the tab list. If _pos is -1, the tab will be added to the end of the tab list
*/
egw_fw_ui_tabs.prototype.addTab = function(_icon, _callback, _closeCallback, _tag)
egw_fw_ui_tabs.prototype.addTab = function(_icon, _callback, _closeCallback, _tag, _pos)
{
var pos = -1;
if (typeof _pos != 'undefined')
pos = _pos;
var tab = new egw_fw_ui_tab(this, this.contHeaderDiv, this.contDiv, _icon, _callback,
_closeCallback, _tag);
this.tabs[this.tabs.length] = tab;
_closeCallback, _tag, pos);
//Insert the tab into the tab list.
var inserted = false;
if (pos > -1)
{
for (var i in this.tabs)
{
if (this.tabs[i].position > pos)
{
this.tabs.splice(i, 0, tab)
inserted = true;
break;
}
}
}
if (pos == -1 || !inserted)
{
this.tabs[this.tabs.length] = tab;
}
if (this.activeTab == null)
this.showTab(tab);