001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace; 029 030import org.opencms.i18n.CmsEncoder; 031import org.opencms.jsp.CmsJspActionElement; 032import org.opencms.main.CmsLog; 033import org.opencms.util.CmsStringUtil; 034 035import java.util.Iterator; 036import java.util.List; 037import java.util.Map; 038import java.util.Map.Entry; 039 040import javax.servlet.http.HttpServletRequest; 041import javax.servlet.http.HttpServletResponse; 042import javax.servlet.jsp.PageContext; 043 044import org.apache.commons.logging.Log; 045 046/** 047 * Provides methods for tab styled dialogs.<p> 048 * 049 * Extend this class in order to create a tab styled dialog and provide the methods 050 * getTabs() and getTabParameterOrder() in the new dialog class which should return lists 051 * which represent the tabs of the dialog.<p> 052 * 053 * This class is used for the following dialogs: 054 * <ul> 055 * <li>User preferences (CmsPreferences.java) 056 * </ul> 057 * <p> 058 * 059 * @since 6.0.0 060 */ 061public abstract class CmsTabDialog extends CmsDialog { 062 063 /** Value for the action: switch the tab. */ 064 public static final int ACTION_SWITCHTAB = 100; 065 066 /** Request parameter value for the action: switch the tab. */ 067 public static final String DIALOG_SWITCHTAB = "switchtab"; 068 069 /** Name of the request parameter for the set button pressed flag. */ 070 public static final String PARAM_SETPRESSED = "setpressed"; 071 /** Name of the request parameter for the current tab. */ 072 public static final String PARAM_TAB = "tab"; 073 074 /** The log object for this class. */ 075 private static final Log LOG = CmsLog.getLog(CmsTabDialog.class); 076 077 /** Stores the currently active tab. */ 078 private int m_activeTab = -1; 079 /** Determines if the "set" button was pressed. */ 080 private String m_paramSetPressed; 081 082 /** Stores the current tab. */ 083 private String m_paramTab; 084 085 /** 086 * Public constructor.<p> 087 * 088 * @param jsp an initialized JSP action element 089 */ 090 public CmsTabDialog(CmsJspActionElement jsp) { 091 092 super(jsp); 093 } 094 095 /** 096 * Public constructor with JSP variables.<p> 097 * 098 * @param context the JSP page context 099 * @param req the JSP request 100 * @param res the JSP response 101 */ 102 public CmsTabDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { 103 104 this(new CmsJspActionElement(context, req, res)); 105 } 106 107 /** 108 * Builds the tab content area of the dialog window.<p> 109 * 110 * @param segment the HTML segment (START / END) 111 * @param title the title String for the dialog window 112 * @param attributes additional attributes for the content <div> area of the tab dialog 113 * @return a tab content area start / end segment 114 */ 115 public String dialogTabContent(int segment, String title, String attributes) { 116 117 if (segment == HTML_START) { 118 StringBuffer result = new StringBuffer(512); 119 // null title is ok, we always want the title headline 120 result.append(dialogHead(title)); 121 result.append("<div class=\"dialogtabstart\" unselectable=\"on\">\n"); 122 result.append("<!-- dialogtabs start -->\n"); 123 result.append(dialogTabRow()); 124 result.append("<div class=\"dialogtabcontent\""); 125 if (attributes != null) { 126 result.append(" " + attributes); 127 } 128 result.append(">\n"); 129 result.append("<!-- dialogcontent start -->\n"); 130 return result.toString(); 131 } else { 132 return "\n<!-- dialogcontent end --></div>\n<!-- dialogtabs end --></div>"; 133 } 134 } 135 136 /** 137 * Returns the end html for the tab content area of the dialog window.<p> 138 * 139 * @return the end html for the tab content area of the dialog window 140 */ 141 public String dialogTabContentEnd() { 142 143 return dialogTabContent(HTML_END, null, null); 144 } 145 146 /** 147 * Returns the start html for the tab content area of the dialog window.<p> 148 * 149 * @param title the title for the dialog 150 * @return the start html for the tab content area of the dialog window 151 */ 152 public String dialogTabContentStart(String title) { 153 154 return dialogTabContent(HTML_START, title, null); 155 } 156 157 /** 158 * Returns the start html for the tab content area of the dialog window.<p> 159 * 160 * @param title the title for the dialog 161 * @param attributes additional attributes for the content <div> area of the tab dialog 162 * @return the start html for the tab content area of the dialog window 163 */ 164 public String dialogTabContentStart(String title, String attributes) { 165 166 return dialogTabContent(HTML_START, title, attributes); 167 } 168 169 /** 170 * Builds the html for the tab row of the tab dialog.<p> 171 * 172 * @return the html for the tab row 173 */ 174 public String dialogTabRow() { 175 176 StringBuffer result = new StringBuffer(512); 177 StringBuffer lineRow = new StringBuffer(256); 178 List<String> tabNames = getTabs(); 179 if (tabNames.size() < 2) { 180 // less than 2 tabs present, do not show them and create a border line 181 result.append( 182 "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"maxwidth\" style=\"empty-cells: show;\">\n"); 183 result.append("<tr>\n"); 184 result.append("\t<td class=\"dialogtabrow\"></td>\n"); 185 result.append("</tr>\n"); 186 result.append("</table>\n"); 187 return result.toString(); 188 } 189 Iterator<String> i = tabNames.iterator(); 190 int counter = 1; 191 int activeTab = getActiveTab(); 192 result.append( 193 "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"maxwidth\" style=\"empty-cells: show;\">\n"); 194 result.append("<tr>\n"); 195 while (i.hasNext()) { 196 // build a tab entry 197 String curTab = i.next(); 198 String curTabLink = "javascript:openTab('" + counter + "');"; 199 if (counter == activeTab) { 200 // create the currently active tab 201 int addDelta = 0; 202 result.append("\t<td class=\"dialogtabactive\""); 203 if (counter == 1) { 204 // for first tab, add special html for correct layout 205 result.append(" style=\"border-left-width: 1px;\""); 206 addDelta = 1; 207 } 208 result.append(">"); 209 result.append("<span class=\"tabactive\" unselectable=\"on\""); 210 result.append(" style=\"width: " + ((curTab.length() * 8) + addDelta) + "px;\""); 211 result.append(">"); 212 result.append(curTab); 213 result.append("</span></td>\n"); 214 lineRow.append("\t<td></td>\n"); 215 } else { 216 // create an inactive tab 217 result.append("\t<td class=\"dialogtab\" unselectable=\"on\">"); 218 result.append("<a class=\"tab\" href=\"" + curTabLink + "\""); 219 result.append(" style=\"width: " + (curTab.length() * 8) + "px;\""); 220 result.append(">"); 221 result.append(curTab); 222 result.append("</a></td>\n"); 223 lineRow.append("\t<td class=\"dialogtabrow\"></td>\n"); 224 } 225 226 counter++; 227 } 228 result.append("\t<td class=\"maxwidth\"></td>\n"); 229 result.append("</tr>\n"); 230 result.append("<tr>\n"); 231 result.append(lineRow); 232 result.append("\t<td class=\"dialogtabrow\"></td>\n"); 233 result.append("</tr>\n"); 234 result.append("</table>\n"); 235 return result.toString(); 236 } 237 238 /** 239 * Returns the number of the currently active tab depending on the request parameter.<p> 240 * 241 * This method has to be called once in initWorkplaceRequestValues after filling the request parameters.<p> 242 * 243 * @return the number of the currently active tab 244 */ 245 public int getActiveTab() { 246 247 if (m_activeTab < 0) { 248 String paramTab = getParamTab(); 249 int tab = 1; 250 if (CmsStringUtil.isNotEmpty(paramTab)) { 251 try { 252 tab = Integer.parseInt(paramTab); 253 } catch (NumberFormatException e) { 254 // do nothing, the first tab is returned 255 if (LOG.isInfoEnabled()) { 256 LOG.info(e.getLocalizedMessage()); 257 } 258 } 259 } 260 setParamTab("" + tab); 261 m_activeTab = tab; 262 return tab; 263 } else { 264 return m_activeTab; 265 } 266 } 267 268 /** 269 * Returns the localized name of the currently active tab.<p> 270 * 271 * @return the localized name of the currently active tab or null if no tab name was found 272 */ 273 public String getActiveTabName() { 274 275 if (m_activeTab < 0) { 276 getActiveTab(); 277 } 278 List<String> tabNames = getTabs(); 279 try { 280 return tabNames.get(m_activeTab - 1); 281 } catch (IndexOutOfBoundsException e) { 282 // should usually never happen 283 if (LOG.isInfoEnabled()) { 284 LOG.info(e.getLocalizedMessage()); 285 } 286 return null; 287 } 288 } 289 290 /** 291 * Returns the value of the setpressed parameter.<p> 292 * 293 * @return the value of the setpressed parameter 294 */ 295 public String getParamSetPressed() { 296 297 return m_paramSetPressed; 298 } 299 300 /** 301 * Returns the value of the tab parameter.<p> 302 * 303 * @return the value of the tab parameter 304 */ 305 public String getParamTab() { 306 307 return m_paramTab; 308 } 309 310 /** 311 * Returns the order of the parameter prefixes for each tab.<p> 312 * 313 * For example, all parameters stored in tab 1 have the prefix "Tab1", i.e. 314 * the getter and setter methods must be getParam<b>Tab1</b>MyParameterName().<p> 315 * 316 * To change the tab order, simply change the order in the String array 317 * and in the generated tab list.<p> 318 * 319 * @return the ordered parameter prefix List 320 * @see org.opencms.workplace.CmsTabDialog#getTabs() 321 */ 322 public abstract List<String> getTabParameterOrder(); 323 324 /** 325 * Returns a list with localized Strings representing the names of the tabs.<p> 326 * 327 * @return list with localized String for the tabs 328 */ 329 public abstract List<String> getTabs(); 330 331 /** 332 * Builds the start html of the page, including setting of DOCTYPE and 333 * inserting a header with the content-type.<p> 334 * 335 * This overloads the default method of the parent class.<p> 336 * 337 * @return the start html of the page 338 */ 339 @Override 340 public String htmlStart() { 341 342 return htmlStart(null); 343 } 344 345 /** 346 * Builds the start html of the page, including setting of DOCTYPE and 347 * inserting a header with the content-type.<p> 348 * 349 * This overloads the default method of the parent class.<p> 350 * 351 * @param helpUrl the key for the online help to include on the page 352 * @return the start html of the page 353 */ 354 @Override 355 public String htmlStart(String helpUrl) { 356 357 String stylesheet = null; 358 if (isPopup()) { 359 stylesheet = "popup.css"; 360 } 361 StringBuffer result = new StringBuffer(super.pageHtmlStyle(HTML_START, null, stylesheet)); 362 if (getSettings().isViewExplorer()) { 363 result.append("<script src=\""); 364 result.append(getSkinUri()); 365 result.append("commons/explorer.js\"></script>\n"); 366 } 367 result.append("<script >\n"); 368 if (helpUrl != null) { 369 result.append("top.head.helpUrl=\""); 370 result.append(helpUrl + "\";\n"); 371 372 } 373 // js to switch the dialog tabs 374 result.append("function openTab(tabValue) {\n"); 375 result.append("\tdocument.forms[0]." + PARAM_TAB + ".value = tabValue;\n"); 376 result.append("\tdocument.forms[0]." + PARAM_ACTION + ".value = \"" + DIALOG_SWITCHTAB + "\";\n"); 377 result.append("\tdocument.forms[0].submit();\n"); 378 result.append("}\n"); 379 // js for the button actions, overwrites CmsDialog.dialogScriptSubmit() js method 380 result.append("function submitAction(actionValue, theForm, formName) {\n"); 381 result.append("\tif (theForm == null) {\n"); 382 result.append("\t\ttheForm = document.forms[formName];\n"); 383 result.append("\t}\n"); 384 result.append("\ttheForm." + PARAM_FRAMENAME + ".value = window.name;\n"); 385 result.append("\tif (actionValue == \"" + DIALOG_SET + "\") {\n"); 386 result.append("\t\ttheForm." + PARAM_ACTION + ".value = \"" + DIALOG_SET + "\";\n"); 387 result.append("\t} else if (actionValue == \"" + DIALOG_CANCEL + "\") {\n"); 388 result.append("\t\ttheForm." + PARAM_ACTION + ".value = \"" + DIALOG_CANCEL + "\";\n"); 389 result.append("\t}\n"); 390 result.append("\ttheForm.submit();\n"); 391 result.append("\treturn false;\n"); 392 result.append("}\n"); 393 result.append("//-->\n</script>\n"); 394 return result.toString(); 395 } 396 397 /** 398 * Returns all initialized parameters of the current workplace class 399 * as hidden field tags that can be inserted in a form.<p> 400 * 401 * This overwrites the method in CmsWorkplace because for each tab, 402 * only the hidden parameters of the non displayed tabs are added.<p> 403 * 404 * @return all initialized parameters of the current workplace class 405 * as hidden field tags that can be inserted in a html form 406 */ 407 @Override 408 public String paramsAsHidden() { 409 410 StringBuffer result = new StringBuffer(512); 411 String activeTab = getTabParameterOrder().get(getActiveTab() - 1); 412 Map<String, Object> params = paramValues(); 413 Iterator<Entry<String, Object>> i = params.entrySet().iterator(); 414 while (i.hasNext()) { 415 Entry<String, Object> entry = i.next(); 416 String param = entry.getKey(); 417 if (!param.startsWith(activeTab)) { 418 // add only parameters which are not displayed in currently active tab 419 result.append("<input type=\"hidden\" name=\""); 420 result.append(param); 421 result.append("\" value=\""); 422 result.append( 423 CmsEncoder.encode(entry.getValue().toString(), getCms().getRequestContext().getEncoding())); 424 result.append("\">\n"); 425 } 426 } 427 return result.toString(); 428 } 429 430 /** 431 * Sets the value of the setpressed parameter.<p> 432 * 433 * @param value the value to set 434 */ 435 public void setParamSetPressed(String value) { 436 437 m_paramSetPressed = value; 438 } 439 440 /** 441 * Sets the value of the tab parameter.<p> 442 * 443 * @param value the value to set 444 */ 445 public void setParamTab(String value) { 446 447 m_paramTab = value; 448 } 449 450}