/* * Copyright (C) 2001, 2002 Red Hat Inc. All Rights Reserved. * * The contents of this file are subject to the CCM Public * License (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of * the License at http://www.redhat.com/licenses/ccmpl.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * */ package com.arsdigita.cms.docmgr.ui; import java.math.BigDecimal; import java.util.ArrayList; import org.apache.log4j.Category; import com.arsdigita.bebop.ActionLink; import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.ColumnPanel; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.Container; import com.arsdigita.bebop.Form; import com.arsdigita.bebop.GridPanel; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Link; import com.arsdigita.bebop.List; import com.arsdigita.bebop.ModalContainer; import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.Paginator; import com.arsdigita.bebop.RequestLocal; import com.arsdigita.bebop.SegmentedPanel; import com.arsdigita.bebop.SimpleComponent; import com.arsdigita.bebop.SimpleContainer; import com.arsdigita.bebop.TabbedPane; import com.arsdigita.bebop.event.ActionEvent; import com.arsdigita.bebop.event.ActionListener; import com.arsdigita.bebop.event.ChangeEvent; import com.arsdigita.bebop.event.ChangeListener; import com.arsdigita.bebop.event.RequestEvent; import com.arsdigita.bebop.event.RequestListener; import com.arsdigita.bebop.form.Date; import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.list.ListCellRenderer; import com.arsdigita.bebop.parameters.BigDecimalParameter; import com.arsdigita.bebop.parameters.DateParameter; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSectionCollection; import com.arsdigita.cms.docmgr.DocMgr; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.kernel.ui.ACSObjectSelectionModel; import com.arsdigita.navigation.ui.admin.CategorySelectionModel; import com.arsdigita.navigation.ui.admin.CategoryTree; import com.arsdigita.xml.Element; /** * User Interface component of the Document Manager application which * which serves as entry-point and navigation tool of the repositories * that a user has subscribed too. * The tree of all subscribed repositories is on the left side, the full * listing of the currently selected directory is on the right side. * * @author Stefan Deusch * */ class BrowseCatDocsPane extends ModalContainer implements DMConstants, ChangeListener, RequestListener { protected static Category s_log = Category.getInstance (CategoryDocsNavigatorPortlet.class.getName()); private Component m_folderContent; private Component m_destinationFolderPanel; private Component m_newFileForm; private Component m_newFolderForm; private Component m_errorMsgPanel; private DestinationFolderForm m_destinationFolderForm; private ErrorMessageLabel m_errorMsgLabel; private Container m_mainBrowseContainer; private ContentSection m_docsContentSection; private TabbedPane m_mainTabPane; private CategoryTree m_tree; private BigDecimalParameter m_docCategoryTreeParam = new BigDecimalParameter(CAT_TREE_ID_PARAM_NAME); private BigDecimalParameter m_docInitCategoryTreeParam = new BigDecimalParameter(CAT_TREE_INIT_ID_PARAM_NAME); //private BigDecimalParameter m_docColumnIdParam = new BigDecimalParameter(DOC_COL_ID_PARAM_NAME); private BigDecimalParameter m_fileIdParam = new BigDecimalParameter(FILE_ID_PARAM_NAME); private StringParameter m_rootAddDocParam= new StringParameter(ROOT_ADD_DOC_PARAM_NAME); private final DateParameter m_startDateParam = new DateParameter(START_DATE_PARAM_NAME); private final DateParameter m_endDateParam = new DateParameter(END_DATE_PARAM_NAME); private ACSObjectSelectionModel m_docCatSelectModel; /** * Default constructor */ public BrowseCatDocsPane() { m_mainTabPane = new TabbedPane(); m_mainBrowseContainer = new BoxPanel(); m_mainTabPane.addTab(WS_BROWSE_TITLE, m_mainBrowseContainer); m_mainTabPane.addTab("Search", new SearchPane()); m_mainBrowseContainer.setClassAttr("sidebarNavPanel"); //m_mainBrowseContainer.setAttribute("navbar-title", "Folders"); ContentSectionCollection csl = ContentSection.getAllSections(); csl.addEqualsFilter("label",DocMgr.getConfig().getContentSection()); if (!csl.next()) { csl.close(); return; } m_docsContentSection = csl.getContentSection(); csl.close(); s_log.debug("m_docs section is "+m_docsContentSection.getName()); m_docCatSelectModel = new ACSObjectSelectionModel(m_docCategoryTreeParam); // FIXME - don't think this will work but it does compile CategorySelectionModel m_categorySelectionModel = new CategorySelectionModel(); m_tree = new CategoryTree(m_categorySelectionModel); // m_tree = new CategoryTree(m_docCatSelectModel, // new RequestLocal() { // protected Object initialValue(PageState s) { // return m_docsContentSection.getRootCategory(); // }} // ); s_log.debug("added category tree"); if(m_tree == null) { s_log.debug(" but the tree was null"); } BoxPanel leftSide = new BoxPanel(); leftSide.setClassAttr("navbar"); m_tree.addChangeListener(this); leftSide.add(m_tree); m_mainBrowseContainer.add(leftSide); /* * Create all panels on the right side. */ SegmentedPanel rightSide = new SegmentedPanel(); rightSide.setClassAttr("main"); m_folderContent = makeContentPanel(rightSide); m_mainBrowseContainer.add(rightSide); add(m_mainTabPane); //m_errorMsgPanel = makeErrorMsgPanel(); //add(m_errorMsgPanel); } /** * Register the page the fist time */ public void register(Page p) { //p.addGlobalStateParam(m_docColumnIdParam); p.addGlobalStateParam(m_rootAddDocParam); p.addGlobalStateParam(m_fileIdParam); p.addGlobalStateParam(m_docCategoryTreeParam); p.addGlobalStateParam(m_docInitCategoryTreeParam); p.addGlobalStateParam(m_endDateParam); p.addGlobalStateParam(m_startDateParam); p.addRequestListener(this); super.register(p); } /** * Checks if a folder is selected in the page state and consequently * hides or shows the Folder Contents or Folder Action panels. */ public void pageRequested(RequestEvent e) { PageState state = e.getPageState(); //BigDecimal fid = (BigDecimal) state.getValue(m_fileIdParam); if (m_tree == null) { s_log.debug("pR: tree is null"); return; } BigDecimal key = (BigDecimal) m_tree.getSelectedKey(state); // start out with root folder selected and open if (key == null) { s_log.debug("key is null"); BigDecimal selected = (BigDecimal) m_docInitCategoryTreeParam.transformValue (state.getRequest()); BigDecimal rootCategoryID = m_docsContentSection.getRootCategory().getID(); if (selected == null) { s_log.debug("selected is null"); key = rootCategoryID; m_tree.expand(rootCategoryID.toString(), state); } else { key = selected; m_tree.expand(rootCategoryID.toString(), state); } m_tree.setSelectedKey(state, key); } } /** * Helper method to communicate selected folder ID to subcomponents. * Return onle non-null after tree has been displayed at least once. */ public BigDecimal getFolderID(PageState state) { return (BigDecimal) m_tree.getSelectedKey(state); } /** * Implementation of the change listener, clicking on the folder * loads the directory on the right side. */ public void stateChanged(ChangeEvent e) { PageState state = e.getPageState(); s_log.debug("stateChanged yo"); // Display folder on the right side corresponding to the key displayFolderContentPanel(state); } /** * Build a panel to display the Folder content of the selected Folder * and add it as a segment to the passed in Segmented Panel. */ private Component makeContentPanel(SegmentedPanel main) { Label info_header = new Label (new GlobalizedMessage("ui.cat.browse.content.header", BUNDLE_NAME)); //folder_info_header.addPrintListener( // new FolderNamePrintListener(m_tree)); GridPanel folderGrid = new GridPanel(1); SimpleContainer pane = new SimpleContainer(); //pane.add(newFileLink); pane.add(new Label(" ")); folderGrid.add(pane, GridPanel.RIGHT | GridPanel.BOTTOM); CategoryItemsBrowser documentsTable = new CategoryItemsBrowser (new CategoryDocModelBuilder(m_docCatSelectModel, ContentItem.DRAFT), m_docCatSelectModel, ContentItem.DRAFT, m_docsContentSection); Paginator paginator = new Paginator(documentsTable,10); documentsTable.setPaginator(paginator); folderGrid.add(paginator); folderGrid.add(documentsTable, GridPanel.LEFT | GridPanel.BOTTOM); folderGrid.add(new Label(" "), GridPanel.RIGHT | GridPanel.BOTTOM); folderGrid.add(new DateSelectorWidget(new BoxPanel(BoxPanel.HORIZONTAL)), GridPanel.CENTER | GridPanel.BOTTOM); return main.addSegment(info_header, folderGrid); } /* * Build panel to display error message when copy/move failed. */ private Component makeErrorMsgPanel() { ColumnPanel c = new ColumnPanel(1); m_errorMsgLabel = new ErrorMessageLabel(); c.add(m_errorMsgLabel); ActionLink link = new ActionLink(ACTION_ERROR_CONTINUE); link.setClassAttr("actionLink"); link.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayFolderContentPanel(e.getPageState()); } }); c.add(link); return c; } public void displayFolderContentPanel(PageState state) { setVisibleComponent(state, m_mainTabPane); } public void displayErrorMsgPanel(PageState state, String action, ArrayList list) { m_errorMsgLabel.setMessages(state, action, list); setVisibleComponent(state, m_errorMsgPanel); } /** * Error message panel that allows to set customized error * messages without showing a tomcat stacktrace */ private static class ErrorMessageLabel extends SimpleComponent implements DMConstants { private RequestLocal m_msgs; private RequestLocal m_action; public ErrorMessageLabel() { m_msgs = new RequestLocal(); m_action = new RequestLocal(); } /** * Set list of file/folder that could not be delete/move/copy. * * @param action file operation (action, move, copy) */ public void setMessages(PageState state, String action, ArrayList msgs) { m_action.set(state, action); m_msgs.set(state, msgs); } public void generateXML(PageState state, Element parent) { Element element = parent.newChildElement("docs:error-label", DOCS_XML_NS); element.addAttribute("action", (String) m_action.get(state)); ArrayList list = (ArrayList) m_msgs.get(state); if (list != null) { for (int i = 0; i < list.size(); i++) { Element item = element.newChildElement("docs:item", DOCS_XML_NS); item.addAttribute("name", ((String) list.get(i))); } } } } /** * Table Cell Renderer that provides clickable Links to follow * directory links . */ private static class DirLinkRenderer implements ListCellRenderer { public Component getComponent(List list, PageState state, Object value, String key, int index, boolean isSelected) { Link link = new Link((String)value, "?" + SEL_FOLDER_ID_PARAM.getName() + "=" + key); return link; } } private class DateSelectorWidget extends Form { public DateSelectorWidget(Container panel) { super("dateSelector",panel); add(new Label("Modified After: ")); add(new Date(m_startDateParam)); add(new Label("Modified Before: ")); add(new Date(m_endDateParam)); add(new Submit("filter", "Filter")); //addInitListener(this); } //public void init(FormSectionEvent e) // throws FormProcessException { // PageState state = e.getPageState(); // // FormData data = e.getFormData(); // data.put(START_DATE_PARAM_NAME, doc.getName()); //} } }