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.list; 029 030import org.opencms.i18n.CmsMessageContainer; 031import org.opencms.i18n.CmsMessages; 032import org.opencms.main.CmsIllegalArgumentException; 033import org.opencms.util.CmsStringUtil; 034import org.opencms.workplace.CmsWorkplace; 035import org.opencms.workplace.tools.A_CmsHtmlIconButton; 036import org.opencms.workplace.tools.CmsHtmlIconButtonStyleEnum; 037 038import java.text.MessageFormat; 039import java.util.ArrayList; 040import java.util.Collections; 041import java.util.Iterator; 042import java.util.List; 043import java.util.Locale; 044 045/** 046 * Html list column definition.<p> 047 * 048 * @since 6.0.0 049 */ 050public class CmsListColumnDefinition { 051 052 /** Standard list button location. */ 053 public static final String ICON_DOWN = "list/arrow_down.png"; 054 055 /** Standard list button location. */ 056 public static final String ICON_UP = "list/arrow_up.png"; 057 058 /** Column alignment. */ 059 private CmsListColumnAlignEnum m_align = CmsListColumnAlignEnum.ALIGN_LEFT; 060 061 /** Comparator for sorting. */ 062 private I_CmsListItemComparator m_comparator = new CmsListItemDefaultComparator(); 063 064 /** Default action. */ 065 private List<CmsListDefaultAction> m_defaultActions = new ArrayList<CmsListDefaultAction>(); 066 067 /** List of actions. */ 068 private List<I_CmsListDirectAction> m_directActions = new ArrayList<I_CmsListDirectAction>(); 069 070 /** Data formatter. */ 071 private I_CmsListFormatter m_formatter; 072 073 /** Customized help text. */ 074 private CmsMessageContainer m_helpText; 075 076 /** Unique id. */ 077 private final String m_id; 078 079 /** List id. */ 080 private String m_listId; 081 082 /** Display name. */ 083 private CmsMessageContainer m_name; 084 085 /** Is printable flag. */ 086 private boolean m_printable = true; 087 088 /** Flag for text wrapping. */ 089 private boolean m_textWrapping; 090 091 /** Visible Flag. */ 092 private boolean m_visible = true; 093 094 /** Column width. */ 095 private String m_width; 096 097 /** The related workplace dialog object. */ 098 private transient A_CmsListDialog m_wp; 099 100 /** 101 * Default Constructor.<p> 102 * 103 * @param id the unique id 104 */ 105 public CmsListColumnDefinition(String id) { 106 107 if (CmsStringUtil.isEmptyOrWhitespaceOnly(id)) { 108 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_LIST_INVALID_NULL_ARG_1, "id")); 109 } 110 m_id = id; 111 } 112 113 /** 114 * Adds a default Action.<p> 115 * 116 * A column could have more than one default action if the visibilities are complementary.<p> 117 * 118 * @param defaultAction the default Action to add 119 */ 120 public void addDefaultAction(CmsListDefaultAction defaultAction) { 121 122 if (m_listId != null) { 123 // set the list id 124 defaultAction.setListId(m_listId); 125 } 126 // set the column id 127 defaultAction.setColumnForLink(this); 128 129 m_defaultActions.add(defaultAction); 130 } 131 132 /** 133 * Adds a new action to the column.<p> 134 * 135 * @param listAction the action to add 136 */ 137 public void addDirectAction(I_CmsListDirectAction listAction) { 138 139 if (m_listId != null) { 140 listAction.setListId(m_listId); 141 } 142 m_directActions.add(listAction); 143 } 144 145 /** 146 * returns the csv output for a cell.<p> 147 * 148 * @param item the item to render the cell for 149 * 150 * @return csv output 151 */ 152 public String csvCell(CmsListItem item) { 153 154 if (!isVisible()) { 155 return ""; 156 } 157 StringBuffer csv = new StringBuffer(512); 158 if (m_formatter == null) { 159 // unformatted output 160 if (item.get(m_id) != null) { 161 // null values are not showed by default 162 csv.append(item.get(m_id).toString()); 163 } else { 164 Iterator<I_CmsListDirectAction> itActions = m_directActions.iterator(); 165 while (itActions.hasNext()) { 166 I_CmsListDirectAction action = itActions.next(); 167 if (action.isVisible()) { 168 action.setItem(item); 169 csv.append(action.getName().key(getWp().getLocale())); 170 } 171 } 172 } 173 } else { 174 // formatted output 175 csv.append(m_formatter.format(item.get(m_id), getWp().getLocale())); 176 } 177 return csv.toString(); 178 } 179 180 /** 181 * Returns the csv output for a column header.<p> 182 * 183 * @return csv header 184 */ 185 public String csvHeader() { 186 187 if (!isVisible()) { 188 return ""; 189 } 190 return getName().key(getWp().getLocale()); 191 } 192 193 /** 194 * Returns the align.<p> 195 * 196 * @return the align 197 */ 198 public CmsListColumnAlignEnum getAlign() { 199 200 return m_align; 201 } 202 203 /** 204 * Returns a default action by id.<p> 205 * 206 * @param actionId the id of the action 207 * 208 * @return the action if found or null 209 */ 210 public CmsListDefaultAction getDefaultAction(String actionId) { 211 212 Iterator<CmsListDefaultAction> it = m_defaultActions.iterator(); 213 while (it.hasNext()) { 214 CmsListDefaultAction action = it.next(); 215 if (action.getId().equals(actionId)) { 216 return action; 217 } 218 } 219 return null; 220 } 221 222 /** 223 * Returns the default Action Ids list.<p> 224 * 225 * @return the default Action Ids list 226 */ 227 public List<String> getDefaultActionIds() { 228 229 List<String> ids = new ArrayList<String>(); 230 Iterator<CmsListDefaultAction> itDefActions = m_defaultActions.iterator(); 231 while (itDefActions.hasNext()) { 232 I_CmsListDirectAction action = itDefActions.next(); 233 ids.add(action.getId()); 234 } 235 return Collections.unmodifiableList(ids); 236 } 237 238 /** 239 * Returns the default Actions list.<p> 240 * 241 * @return a list of {@link CmsListDefaultAction} objects 242 */ 243 public List<CmsListDefaultAction> getDefaultActions() { 244 245 return Collections.unmodifiableList(m_defaultActions); 246 } 247 248 /** 249 * Returns a direct action by id.<p> 250 * 251 * @param actionId the id of the action 252 * 253 * @return the action if found or null 254 */ 255 public I_CmsListDirectAction getDirectAction(String actionId) { 256 257 Iterator<I_CmsListDirectAction> it = m_directActions.iterator(); 258 while (it.hasNext()) { 259 I_CmsListDirectAction action = it.next(); 260 if (action.getId().equals(actionId)) { 261 return action; 262 } 263 } 264 return null; 265 } 266 267 /** 268 * Returns the direct Action Ids list.<p> 269 * 270 * @return the direct Action Ids list 271 */ 272 public List<String> getDirectActionIds() { 273 274 List<String> ids = new ArrayList<String>(); 275 Iterator<I_CmsListDirectAction> itDirActions = m_directActions.iterator(); 276 while (itDirActions.hasNext()) { 277 I_CmsListDirectAction action = itDirActions.next(); 278 ids.add(action.getId()); 279 } 280 return Collections.unmodifiableList(ids); 281 } 282 283 /** 284 * Returns all direct actions.<p> 285 * 286 * @return a list of <code>{@link I_CmsListDirectAction}</code>s. 287 */ 288 public List<I_CmsListDirectAction> getDirectActions() { 289 290 return Collections.unmodifiableList(m_directActions); 291 } 292 293 /** 294 * Returns the data formatter.<p> 295 * 296 * @return the data formatter 297 */ 298 public I_CmsListFormatter getFormatter() { 299 300 return m_formatter; 301 } 302 303 /** 304 * Returns the customized help Text.<p> 305 * 306 * if <code>null</code> a default help text indicating the sort actions is used.<p> 307 * 308 * @return the customized help Text 309 */ 310 public CmsMessageContainer getHelpText() { 311 312 return m_helpText; 313 } 314 315 /** 316 * Returns the id.<p> 317 * 318 * @return the id 319 */ 320 public String getId() { 321 322 return m_id; 323 } 324 325 /** 326 * Returns the comparator, used for sorting.<p> 327 * 328 * if no comparator was set, the default list item comparator is used.<p> 329 * 330 * @return the comparator 331 * 332 * @see CmsListItemDefaultComparator 333 */ 334 public I_CmsListItemComparator getListItemComparator() { 335 336 return m_comparator; 337 } 338 339 /** 340 * Returns the name.<p> 341 * 342 * @return the name 343 */ 344 public CmsMessageContainer getName() { 345 346 return m_name; 347 } 348 349 /** 350 * Returns the width.<p> 351 * 352 * @return the width 353 */ 354 public String getWidth() { 355 356 return m_width; 357 } 358 359 /** 360 * Returns the workplace dialog object.<p> 361 * 362 * @return the workplace dialog object 363 */ 364 public A_CmsListDialog getWp() { 365 366 return m_wp; 367 } 368 369 /** 370 * returns the html for a cell.<p> 371 * 372 * @param item the item to render the cell for 373 * @param isPrintable if the list is to be printed 374 * 375 * @return html code 376 */ 377 public String htmlCell(CmsListItem item, boolean isPrintable) { 378 379 StringBuffer html = new StringBuffer(512); 380 Iterator<I_CmsListDirectAction> itActions = m_directActions.iterator(); 381 while (itActions.hasNext()) { 382 I_CmsListDirectAction action = itActions.next(); 383 action.setItem(item); 384 boolean enabled = action.isEnabled(); 385 if (isPrintable) { 386 action.setEnabled(false); 387 } 388 html.append(action.buttonHtml()); 389 if (isPrintable) { 390 action.setEnabled(enabled); 391 } 392 } 393 if (!m_defaultActions.isEmpty()) { 394 Iterator<CmsListDefaultAction> itDefaultActions = m_defaultActions.iterator(); 395 while (itDefaultActions.hasNext()) { 396 CmsListDefaultAction defAction = itDefaultActions.next(); 397 defAction.setItem(item); 398 boolean enabled = defAction.isEnabled(); 399 if (isPrintable) { 400 defAction.setEnabled(false); 401 } 402 html.append(defAction.buttonHtml()); 403 if (isPrintable) { 404 defAction.setEnabled(enabled); 405 } 406 } 407 } else { 408 if (m_formatter == null) { 409 // unformatted output 410 if (item.get(m_id) != null) { 411 // null values are not showed by default 412 html.append(item.get(m_id).toString()); 413 } 414 } else { 415 // formatted output 416 html.append(m_formatter.format(item.get(m_id), getWp().getLocale())); 417 } 418 } 419 html.append("\n"); 420 return html.toString(); 421 } 422 423 /** 424 * Returns the html code for a column header.<p> 425 * 426 * @param list the list to generate the header code for 427 * 428 * @return html code 429 */ 430 public String htmlHeader(CmsHtmlList list) { 431 432 String listId = list.getId(); 433 String sortedCol = list.getSortedColumn(); 434 CmsListOrderEnum order = list.getCurrentSortOrder(); 435 436 StringBuffer html = new StringBuffer(512); 437 Locale locale = getWp().getLocale(); 438 CmsMessages messages = Messages.get().getBundle(locale); 439 html.append("<th"); 440 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getWidth())) { 441 html.append(" width='"); 442 html.append(getWidth()); 443 html.append("'"); 444 } 445 if (!isTextWrapping()) { 446 html.append(" style='white-space: nowrap;'"); 447 } 448 html.append(">\n"); 449 450 boolean isSorted = getId().equals(sortedCol); 451 CmsListOrderEnum nextOrder = CmsListOrderEnum.ORDER_ASCENDING; 452 if (isSorted && (order == CmsListOrderEnum.ORDER_ASCENDING)) { 453 nextOrder = CmsListOrderEnum.ORDER_DESCENDING; 454 } 455 // button 456 String id = listId + getId() + "Sort"; 457 String onClic = "listSort('" + listId + "', '" + getId() + "');"; 458 String helpText = null; 459 if (m_helpText != null) { 460 helpText = new MessageFormat(m_helpText.key(locale), locale).format(new Object[] {getName().key(locale)}); 461 } else { 462 if (isSorteable()) { 463 if (nextOrder.equals(CmsListOrderEnum.ORDER_ASCENDING)) { 464 helpText = messages.key(Messages.GUI_LIST_COLUMN_ASC_SORT_1, new Object[] {getName().key(locale)}); 465 } else { 466 helpText = messages.key(Messages.GUI_LIST_COLUMN_DESC_SORT_1, new Object[] {getName().key(locale)}); 467 } 468 } else { 469 helpText = messages.key(Messages.GUI_LIST_COLUMN_NO_SORT_1, new Object[] {getName().key(locale)}); 470 } 471 } 472 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getWidth()) && (getWidth().indexOf('%') < 0)) { 473 html.append("\t<div style='display:block; width: "); 474 html.append(getWidth()); 475 html.append("px;'>\n"); 476 } 477 String sortArrow = ""; 478 // sort order marker 479 if (isSorted) { 480 if (nextOrder == CmsListOrderEnum.ORDER_ASCENDING) { 481 sortArrow = "<img src='" + CmsWorkplace.getSkinUri() + ICON_DOWN + "' alt=''> "; 482 } else { 483 sortArrow = "<img src='" + CmsWorkplace.getSkinUri() + ICON_UP + "' alt=''> "; 484 } 485 } 486 html.append( 487 A_CmsHtmlIconButton.defaultButtonHtml( 488 CmsHtmlIconButtonStyleEnum.SMALL_ICON_TEXT, 489 id, 490 id, 491 getName().key(locale), 492 helpText, 493 list.isPrintable() ? false : isSorteable(), 494 null, 495 null, 496 onClic, 497 false, 498 sortArrow)); 499 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getWidth()) && (getWidth().indexOf('%') < 0)) { 500 html.append("\t</div>\n"); 501 } 502 html.append("</th>\n"); 503 return html.toString(); 504 } 505 506 /** 507 * Returns the printable .<p> 508 * 509 * @return the printable flag 510 */ 511 public boolean isPrintable() { 512 513 return m_printable; 514 } 515 516 /** 517 * Returns the sorteable.<p> 518 * 519 * @return the sorteable 520 */ 521 public boolean isSorteable() { 522 523 return getListItemComparator() != null; 524 } 525 526 /** 527 * Returns the text Wrapping flag.<p> 528 * 529 * @return the text Wrapping flag 530 */ 531 public boolean isTextWrapping() { 532 533 return m_textWrapping; 534 } 535 536 /** 537 * Returns the visible.<p> 538 * 539 * @return the visible 540 */ 541 public boolean isVisible() { 542 543 return m_visible; 544 } 545 546 /** 547 * Removes the default action from this column by id.<p> 548 * 549 * @param actionId the id of the action to remove 550 * 551 * @return the action if found or <code>null</code> 552 */ 553 public CmsListDefaultAction removeDefaultAction(String actionId) { 554 555 Iterator<CmsListDefaultAction> it = m_defaultActions.iterator(); 556 while (it.hasNext()) { 557 CmsListDefaultAction action = it.next(); 558 if (action.getId().equals(actionId)) { 559 it.remove(); 560 return action; 561 } 562 } 563 return null; 564 } 565 566 /** 567 * Removes a direct action from this column by id.<p> 568 * 569 * @param actionId the id of the action to remove 570 * 571 * @return the action if found or <code>null</code> 572 */ 573 public I_CmsListDirectAction removeDirectAction(String actionId) { 574 575 Iterator<I_CmsListDirectAction> it = m_directActions.iterator(); 576 while (it.hasNext()) { 577 I_CmsListDirectAction action = it.next(); 578 if (action.getId().equals(actionId)) { 579 it.remove(); 580 return action; 581 } 582 } 583 return null; 584 } 585 586 /** 587 * Sets the align.<p> 588 * 589 * @param align the align to set 590 */ 591 public void setAlign(CmsListColumnAlignEnum align) { 592 593 m_align = align; 594 } 595 596 /** 597 * Sets the data formatter.<p> 598 * 599 * @param formatter the data formatter to set 600 */ 601 public void setFormatter(I_CmsListFormatter formatter) { 602 603 m_formatter = formatter; 604 // set the formatter for all default actions 605 Iterator<CmsListDefaultAction> it = m_defaultActions.iterator(); 606 while (it.hasNext()) { 607 CmsListDefaultAction action = it.next(); 608 action.setColumnForLink(this); 609 } 610 } 611 612 /** 613 * Sets the customized help Text.<p> 614 * 615 * if <code>null</code> a default help text indicating the sort actions is used.<p> 616 * 617 * @param helpText the customized help Text to set 618 */ 619 public void setHelpText(CmsMessageContainer helpText) { 620 621 m_helpText = helpText; 622 } 623 624 /** 625 * Sets the comparator, used for sorting.<p> 626 * 627 * @param comparator the comparator to set 628 */ 629 public void setListItemComparator(I_CmsListItemComparator comparator) { 630 631 m_comparator = comparator; 632 } 633 634 /** 635 * Sets the name.<p> 636 * 637 * @param name the name to set 638 */ 639 public void setName(CmsMessageContainer name) { 640 641 m_name = name; 642 } 643 644 /** 645 * Sets the printable flag.<p> 646 * 647 * @param printable the printable flag to set 648 */ 649 public void setPrintable(boolean printable) { 650 651 m_printable = printable; 652 } 653 654 /** 655 * Indicates if the current column is sorteable or not.<p> 656 * 657 * if <code>true</code> a default list item comparator is used.<p> 658 * 659 * if <code>false</code> any previously set list item comparator is removed.<p> 660 * 661 * @param sorteable the sorteable flag 662 */ 663 public void setSorteable(boolean sorteable) { 664 665 if (sorteable) { 666 setListItemComparator(new CmsListItemDefaultComparator()); 667 } else { 668 setListItemComparator(null); 669 } 670 } 671 672 /** 673 * Sets the text Wrapping flag.<p> 674 * 675 * @param textWrapping the text Wrapping flag to set 676 */ 677 public void setTextWrapping(boolean textWrapping) { 678 679 m_textWrapping = textWrapping; 680 } 681 682 /** 683 * Sets the visible.<p> 684 * 685 * This will set also the printable flag to <code>false</code>.<p> 686 * 687 * @param visible the visible to set 688 */ 689 public void setVisible(boolean visible) { 690 691 m_visible = visible; 692 if (!m_visible) { 693 setPrintable(false); 694 } 695 } 696 697 /** 698 * Sets the width.<p> 699 * 700 * @param width the width to set 701 */ 702 public void setWidth(String width) { 703 704 m_width = width; 705 } 706 707 /** 708 * Sets the workplace dialog object.<p> 709 * 710 * @param wp the workplace dialog object to set 711 */ 712 public void setWp(A_CmsListDialog wp) { 713 714 m_wp = wp; 715 Iterator<I_CmsListDirectAction> itActs = getDirectActions().iterator(); 716 while (itActs.hasNext()) { 717 I_CmsListDirectAction action = itActs.next(); 718 action.setWp(wp); 719 } 720 Iterator<CmsListDefaultAction> itDefActs = getDefaultActions().iterator(); 721 while (itDefActs.hasNext()) { 722 CmsListDefaultAction action = itDefActs.next(); 723 action.setWp(wp); 724 } 725 } 726 727 /** 728 * Sets the id of the list.<p> 729 * 730 * @param listId the id of the list 731 */ 732 /*package*/void setListId(String listId) { 733 734 m_listId = listId; 735 } 736}