/** * Copyright 1999-2009 The Pegadi Team * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An application for listing and selecting articles. This is mostly built * around the {@link ArticleList pegadi.articlelist.ArticleList} component. * * @author Jørgen Binningsbø <jb@underdusken.no> * @author Håvard Wigtil <havardw at pvv.org> */ package org.pegadi.lister; import com.kitfox.svg.SVGCache; import com.kitfox.svg.app.beans.SVGIcon; import no.dusken.common.model.Person; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.xmlgraphics.util.MimeConstants; import org.pegadi.articlelist.ArticleList; import org.pegadi.articlelist.Grouper; import org.pegadi.articlesearch.SearchPanel; import org.pegadi.artis.Artis; import org.pegadi.artis.Artis.PrintDialog; import org.pegadi.maildialog.MailDialog; import org.pegadi.model.*; import org.pegadi.permissions.ArticlePermissions; import org.pegadi.permissions.GlobalPermissions; import org.pegadi.publisher.FOPPrintPublisher; import org.pegadi.publisher.FOPPrintRenderer; import org.pegadi.server.NoAccessException; import org.pegadi.sqlsearch.SearchTerm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamSource; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.print.PrinterJob; import java.net.InetAddress; import java.net.URI; import java.net.URL; import java.net.UnknownHostException; import java.rmi.RemoteException; import java.text.MessageFormat; import java.util.*; public class Lister extends JFrame { JPanel contentPane; JPanel topPanel = new JPanel(); BorderLayout borderLayout1 = new BorderLayout(); JMenuBar jMenuBar1 = new JMenuBar(); JMenu mainMenu = new JMenu(); JMenu editMenu = new JMenu(); JMenuItem groupMenuItem = new JMenuItem(); JMenuItem columnsMenuItem = new JMenuItem(); JMenuItem chooseArticlesMenuItem = new JMenuItem(); JMenuItem prefsMenuItem = new JMenuItem(); JMenu changeArticleStatusMenu = new JMenu(); JScrollPane jScrollPane1 = new JScrollPane(); ArticleList articleList; int[] myColumns = {0, 2, 3, 1, 5, 6, 8, 7}; Person mySelf; Locale currentLocale; ResourceBundle messages; /** * The string describeing the current selection */ String artSelString; /** * Application preferences. */ protected Properties prefs; /** * Preferences domain. */ static final String PREFS_DOMAIN = "Lister"; static final String PREFS_SEL_CLASS = "SelectionClass"; static final String PREFS_SEL_ID = "SelectionID"; static final String PREFS_SEL_DESC = "SelectionDescription"; static final String PREFS_SEL_REMEMBER = "RememberSelection"; JPopupMenu popup; JMenu sendMailTo; AbstractAction refreshAction; AbstractAction editAction; AbstractAction newAction; AbstractAction aboutAction; AbstractAction publishAction; AbstractAction printListAction; AbstractAction printArticleAction; AbstractAction deleteAction; AbstractAction sendMailToJournalistAction; AbstractAction exitAction; AbstractAction[] changeArticleStatusActions; protected JToolBar toolBar = new JToolBar(); String lastPublishedToDir; /** * The panel used to contruct searchTerms and initate a search */ SearchPanel searchPanel; /** * The current searh term */ SearchTerm searchTerm; private final Logger log = LoggerFactory.getLogger(getClass()); /** * Constructs the frame and initalizes the articlelist with * the authenticated user's articles. */ public Lister() { enableEvents(AWTEvent.WINDOW_EVENT_MASK); ImageIcon icon = new ImageIcon(getClass().getResource("/images/pegadi.gif")); setIconImage(icon.getImage()); currentLocale = Locale.getDefault(); try { messages = ResourceBundle.getBundle("org.pegadi.lister.ListerStrings", currentLocale); } catch (Exception e) { log.error("Error getting resources", e); } articleList = new ArticleList(); articleList.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { articleList_actionPerformed(e); } }); try { createActions(); jbInit(); } catch (Exception e) { log.error("Error initialising GUI", e); } try { searchTerm = searchPanel.getSearchTerm(); refreshArticles(); } catch (Exception e) { log.error("Error getting articles", e); } // check if this user is layout, and thus can publish. try { if (LoginContext.server.hasGlobalPermission(LoginContext.server.getUserID(LoginContext.sessionKey), GlobalPermissions.LEGACY_PUBLISH_ARTICLES, LoginContext.sessionKey)) publishAction.setEnabled(true); else publishAction.setEnabled(false); } catch (Exception se) { log.error("Error checking user publishing privileges", se); } articleList.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { articleList_stateChanged(e); } }); loadPrefs(); try { mySelf = LoginContext.server.getSessionUser(LoginContext.sessionKey); } catch (Exception e) { log.error("Error getting myself from server", e); } validate(); articleList.updateColumns(myColumns); articleList.revalidate(); refreshArticles(); } /** * Load prefs from the server and apply. */ protected void loadPrefs() { try { prefs = LoginContext.server.getPreferences(PREFS_DOMAIN, LoginContext.sessionKey); } catch (Exception e) { log.error("Exception getting preferences for domain {}", PREFS_DOMAIN, e); prefs = new Properties(); } String sclass = prefs.getProperty(PREFS_SEL_CLASS); if (sclass == null) { sclass = Person.class.toString(); prefs.put(PREFS_SEL_CLASS, sclass); } String sID = prefs.getProperty(PREFS_SEL_ID); if (sID == null) { sID = "26"; // Hey, it's me! (havardw) prefs.put(PREFS_SEL_ID, sID); } artSelString = prefs.getProperty(PREFS_SEL_DESC); String remember = prefs.getProperty(PREFS_SEL_REMEMBER); if (remember == null) { remember = "false"; prefs.put(PREFS_SEL_REMEMBER, remember); } // Reset last selection to "My articles" if (!Boolean.valueOf(remember)) { prefs.put(PREFS_SEL_CLASS, Person.class.toString()); try { prefs.put(PREFS_SEL_ID, String.valueOf(LoginContext.server.getUserID(LoginContext.sessionKey))); } catch (Exception e) { log.error("Unable to get user ID, setting to 0", e); prefs.put(PREFS_SEL_ID, "0"); } artSelString = messages.getString("selection_myself"); } } /** * Refreshes the article list by re-reading from server. */ protected void refreshArticles() { try { java.util.List<Article> articles = LoginContext.server.getArticlesBySearchTerm(searchTerm, LoginContext.sessionKey); articleList.regroup(articles); articleList.revalidate(); articleList.repaint(); } catch (Exception ex) { log.error("Exception updating articles.", ex); } // Currently no selection, update the actions editAction.setEnabled(false); aboutAction.setEnabled(false); publishAction.setEnabled(false); deleteAction.setEnabled(false); printArticleAction.setEnabled(false); sendMailTo.setEnabled(false); changeArticleStatusMenu.setEnabled(false); } protected boolean displayDeleteWarning() { //JOptionPane warning = new JoptionPane(); int warning = JOptionPane.showConfirmDialog(this, messages.getString("confirm_delete"), messages.getString("delete_articleitem"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (warning == JOptionPane.YES_OPTION) { return true; } else { log.debug("article deletion cancelled by user"); return false; }//end if } /** * Creates an SVGIcon that can be used by the UI. * @param iconPath the path of the svg file * @return an SVGIcon */ protected SVGIcon initSvgIcon(URL iconPath) { URI iconURI = SVGCache.getSVGUniverse().loadSVG(iconPath); SVGIcon icon = new SVGIcon(); icon.setSvgURI(iconURI); icon.setAntiAlias(true); icon.setPreferredSize(new Dimension(32,32)); icon.setScaleToFit(true); return icon; } /** * Create all actions used by the UI. */ protected void createActions() { //ImageIcon refreshIcon = new ImageIcon(getClass().getResource(messages.getString("icon_refresh"))); SVGIcon refreshIcon = initSvgIcon(getClass().getResource(messages.getString("icon_refresh"))); refreshAction = new AbstractAction(messages.getString("refresh"), refreshIcon) { public void actionPerformed(ActionEvent e) { refreshArticles(); } }; //ImageIcon editIcon = new ImageIcon(getClass().getResource(messages.getString("icon_edit"))); SVGIcon editIcon = initSvgIcon(getClass().getResource(messages.getString("icon_edit"))); editAction = new AbstractAction(messages.getString("edit_button"), editIcon) { public void actionPerformed(ActionEvent e) { editAction_actionPerformed(e); } }; //ImageIcon newIcon = new ImageIcon(getClass().getResource(messages.getString("icon_new"))); SVGIcon newIcon = initSvgIcon(getClass().getResource(messages.getString("icon_new"))); newAction = new AbstractAction(messages.getString("new_button"), newIcon) { public void actionPerformed(ActionEvent e) { newAction_actionPerformed(e); } }; //ImageIcon aboutIcon = new ImageIcon(getClass().getResource(messages.getString("icon_about"))); SVGIcon aboutIcon = initSvgIcon(getClass().getResource(messages.getString("icon_about"))); aboutAction = new AbstractAction(messages.getString("about_button"), aboutIcon) { public void actionPerformed(ActionEvent e) { aboutAction_actionPerformed(e); } }; //ImageIcon publishIcon = new ImageIcon(getClass().getResource(messages.getString("icon_publish"))); SVGIcon publishIcon = initSvgIcon(getClass().getResource(messages.getString("icon_publish"))); publishAction = new AbstractAction(messages.getString("publish_button"), publishIcon) { public void actionPerformed(ActionEvent e) { publishAction_actionPerformed(e); } }; //ImageIcon printIcon = new ImageIcon(getClass().getResource(messages.getString("icon_print"))); SVGIcon printIcon = initSvgIcon(getClass().getResource(messages.getString("icon_print"))); printListAction = new AbstractAction(messages.getString("print_button"), printIcon) { public void actionPerformed(ActionEvent e) { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); printArticleList(); setCursor(Cursor.getDefaultCursor()); } }; printArticleAction = new AbstractAction(messages.getString("print_articleitem"), printIcon) { public void actionPerformed(ActionEvent e) { printArticleAction_actionPerformed(e); } }; //ImageIcon deleteIcon = new ImageIcon(getClass().getResource(messages.getString("icon_delete"))); SVGIcon deleteIcon = initSvgIcon(getClass().getResource(messages.getString("icon_delete"))); deleteAction = new AbstractAction(messages.getString("delete_articleitem"), deleteIcon) { public void actionPerformed(ActionEvent e) { deleteAction_actionPerformed(e); } }; sendMailToJournalistAction = new AbstractAction(messages.getString("sendmail_journalist"), null) { public void actionPerformed(ActionEvent e) { sendMailToJournalistAction_actionPerformed(e); } }; //ImageIcon exitIcon = new ImageIcon(getClass().getResource(messages.getString("icon_close"))); SVGIcon exitIcon = initSvgIcon(getClass().getResource(messages.getString("icon_close"))); exitAction = new AbstractAction(messages.getString("quit_button"), exitIcon) { public void actionPerformed(ActionEvent e) { exitAction_actionPerformed(e); } }; java.util.List<ArticleStatus> statuses = null; try { statuses = LoginContext.server.getArticleStatuses(LoginContext.sessionKey); } catch (java.rmi.RemoteException e) { log.error("Error getting statuses from server", e); } changeArticleStatusActions = new AbstractAction[statuses.size()]; for (int i = 0; i < changeArticleStatusActions.length; i++) { changeArticleStatusActions[i] = new ChangeArticleStatusAction(statuses.get(i)); } } //Component initialization private void jbInit() { contentPane = (JPanel) this.getContentPane(); contentPane.setLayout(borderLayout1); this.setSize(new Dimension(790, 573)); this.setTitle("Lister"); mainMenu.setText(messages.getString("main_menu")); editMenu.setText(messages.getString("edit_menu")); changeArticleStatusMenu.setText(messages.getString("changearticlestatus_menu")); SVGIcon statusIcon = initSvgIcon(getClass().getResource(messages.getString("icon_changearticlestatus"))); changeArticleStatusMenu.setIcon(statusIcon); //changeArticleStatusMenu.setIcon(new ImageIcon(getClass().getResource(messages.getString("icon_changearticlestatus")))); groupMenuItem.setText(messages.getString("group_menuitem")); groupMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { groupMenuItem_actionPerformed(e); } }); prefsMenuItem.setText(messages.getString("prefs_menuitem")); SVGIcon prefsIcon = initSvgIcon(getClass().getResource(messages.getString("icon_prefs"))); prefsMenuItem.setIcon(prefsIcon); //prefsMenuItem.setIcon(new ImageIcon(getClass().getResource(messages.getString("icon_prefs")))); prefsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { prefsMenuItem_actionPerformed(e); } }); columnsMenuItem.setText(messages.getString("columns_menuitem")); JMenuItem quitMenuItem = new JMenuItem(messages.getString("quit_button"), new ImageIcon(getClass().getResource(messages.getString("icon_close")))); quitMenuItem.setToolTipText(messages.getString("tip_quit_button")); quitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(87, java.awt.event.KeyEvent.CTRL_MASK, false)); quitMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { quitMenuItem_actionPerformed(e); } }); jMenuBar1.add(mainMenu); jMenuBar1.add(editMenu); editMenu.add(groupMenuItem); //FIXME: This is now obsolete because of the new search panel. //editMenu.add(prefsMenuItem); JMenuItem newMenuItem = mainMenu.add(newAction); newMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, java.awt.event.KeyEvent.CTRL_MASK, false)); JMenuItem aboutMenuItem = mainMenu.add(aboutAction); aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(73, java.awt.event.KeyEvent.CTRL_MASK, false)); JMenuItem editMenuItem = mainMenu.add(editAction); editMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(69, java.awt.event.KeyEvent.CTRL_MASK, false)); JMenuItem deleteMenuItem = mainMenu.add(deleteAction); deleteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(68, java.awt.event.KeyEvent.CTRL_MASK, false)); JMenuItem publishMenuItem = mainMenu.add(publishAction); publishMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(83, java.awt.event.KeyEvent.CTRL_MASK, false)); JMenuItem printMenuItem = mainMenu.add(printListAction); printMenuItem.setMnemonic(messages.getString("print_menuitem").charAt(0)); printMenuItem.setText(messages.getString("print_menuitem")); printMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(80, java.awt.event.KeyEvent.CTRL_MASK, false)); mainMenu.addSeparator(); mainMenu.add(quitMenuItem); setJMenuBar(jMenuBar1); searchPanel = new SearchPanel(); searchPanel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setCursor(new Cursor(Cursor.WAIT_CURSOR)); searchPanel_actionPerformed(); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } }); JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setRightComponent(jScrollPane1); splitPane.setLeftComponent(searchPanel); contentPane.add(splitPane, BorderLayout.CENTER); jScrollPane1.getViewport().add(articleList, null); contentPane.add(topPanel, BorderLayout.NORTH); topPanel.setLayout(new GridLayout(0, 1)); topPanel.add(toolBar); popup = new JPopupMenu(); popup.add(editAction); popup.add(aboutAction); for (AbstractAction changeArticleStatusAction : changeArticleStatusActions) { JMenuItem item = new JMenuItem(changeArticleStatusAction); changeArticleStatusMenu.add(item); } popup.add(changeArticleStatusMenu); popup.add(publishAction); popup.add(deleteAction); popup.add(printArticleAction); sendMailTo = new JMenu(messages.getString("sendmail")); //ImageIcon sendMailIcon = new ImageIcon(getClass().getResource(messages.getString("icon_sendmail"))); SVGIcon mailIcon = initSvgIcon(getClass().getResource(messages.getString("icon_sendmail"))); sendMailTo.setIcon(mailIcon); sendMailTo.add(sendMailToJournalistAction); popup.add(sendMailTo); articleList.setPopupMenu(popup); JButton tempButton; tempButton = toolBar.add(refreshAction); tempButton.setToolTipText((String) refreshAction.getValue(Action.NAME)); SVGIcon refreshIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_refresh_disabled"))); tempButton.setDisabledIcon(refreshIconDisabled); tempButton = toolBar.add(printListAction); tempButton.setToolTipText((String) printListAction.getValue(Action.NAME)); SVGIcon printIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_print_disabled"))); tempButton.setDisabledIcon(printIconDisabled); toolBar.addSeparator(); tempButton = toolBar.add(newAction); tempButton.setToolTipText((String) newAction.getValue(Action.NAME)); SVGIcon newIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_new_disabled"))); tempButton.setDisabledIcon(newIconDisabled); tempButton = toolBar.add(editAction); tempButton.setToolTipText((String) editAction.getValue(Action.NAME)); SVGIcon editIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_edit_disabled"))); tempButton.setDisabledIcon(editIconDisabled); tempButton = toolBar.add(aboutAction); tempButton.setToolTipText((String) aboutAction.getValue(Action.NAME)); SVGIcon aboutIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_about_disabled"))); tempButton.setDisabledIcon(aboutIconDisabled); tempButton = toolBar.add(publishAction); tempButton.setToolTipText((String) publishAction.getValue(Action.NAME)); SVGIcon publishIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_publish_disabled"))); tempButton.setDisabledIcon(publishIconDisabled); toolBar.addSeparator(); tempButton = toolBar.add(exitAction); tempButton.setToolTipText((String) exitAction.getValue(Action.NAME)); SVGIcon exitIconDisabled = initSvgIcon(getClass().getResource(messages.getString("icon_close_disabled"))); tempButton.setDisabledIcon(exitIconDisabled); tempButton.setContentAreaFilled(true); toolBar.setAlignmentX(0); } public void searchPanel_actionPerformed() { searchTerm = searchPanel.getSearchTerm(); refreshArticles(); } //Overridden so we can exit when window is closed protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { dispose(); } } void newAction_actionPerformed(ActionEvent e) { this.setCursor(new Cursor(Cursor.WAIT_CURSOR)); Article newArt = new Article(); java.util.List<Publication> publist = null; try { publist = LoginContext.server.getActivePublications(LoginContext.sessionKey); } catch (java.rmi.RemoteException ex) { log.error("Exception getting active publications", ex); } if (publist != null && publist.size() > 0) newArt.setPublication(publist.get(0)); ArticleDialog artDialog = new ArticleDialog(this, newArt); artDialog.pack(); artDialog.setLocation(this.getLocation().x + 50, this.getLocation().y + 50); this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); artDialog.setVisible(true); if (artDialog.dialogResult()) { boolean saved = false; Article article = artDialog.getArticle(); int articleID; while (!saved) { try { articleID = LoginContext.server.saveArticle(article, LoginContext.sessionKey); if (articleID > 0) { // Save was successful, and article got an ID saved = true; article.setId(articleID); LoginContext.server.setCoJournalistsForArticle(articleID, artDialog.getCoJournalists(), LoginContext.sessionKey); } else if (articleID == 0) { // Save was successful saved = true; } } catch (Exception ee) { log.error("Exception saving changed article", ee); int d = JOptionPane.showConfirmDialog(this, messages.getString("save_error_msg"), messages.getString("save_error_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.NO_OPTION) { saved = true; } } } } refreshArticles(); } void openArticleInArtis(Article art) { boolean canEdit = false; try { canEdit = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.EDIT_ARTICLE, art.getId(), LoginContext.sessionKey); } catch (RemoteException e1) { log.error("Connection error", e1); } if (canEdit) { this.setCursor(new Cursor(Cursor.WAIT_CURSOR)); ArticleLock lock = null; try { lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey); } catch (RemoteException rme) { log.error("Connection error", rme); } boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey); // Is this lock owned by user? boolean isSameUser = false; try { isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername()); } catch (RemoteException rme) { log.error("Connection error", rme); } if (!lockIsMine && isSameUser) { String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch (UnknownHostException e) { hostname = lock.getHost(); } String rawmessage = messages.getString("hijack_lock_msg"); Object[] args = {hostname}; String message = MessageFormat.format(rawmessage, args); int d = JOptionPane.showConfirmDialog(this, message, messages.getString("hijack_lock_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.YES_OPTION) { try { lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey); } catch (RemoteException rme) { log.error("Connecion error", rme); } lockIsMine = true; } if (d == JOptionPane.NO_OPTION) { this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); return; } } Article fresh; try { fresh = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey); } catch (Exception e) { log.error("Could not get article from server!", e); JOptionPane.showMessageDialog(this, "Sorry Mac. Could not get articlelock", messages.getString("locked_error"), JOptionPane.ERROR_MESSAGE); return; } Artis anArtis; //If article is already opened in an Artis window do not mess with its size and position if (Artis.isOpen(fresh)) { anArtis = Artis.fetchUniqueArtis(fresh, lock); } else { anArtis = Artis.fetchUniqueArtis(fresh, lock); anArtis.setSize(new Dimension((int) (getSize().getWidth() + 100), (int) (getSize().getHeight() + 50))); Point location = getLocation(); location.translate(20, 20); anArtis.setLocation(location); } this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if(!lockIsMine) { String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch(UnknownHostException e) { hostname = lock.getHost(); } String rawmessage = messages.getString("locked_error_preview"); Object[] args = {lock.getUsername(), hostname}; String message = MessageFormat.format(rawmessage, args); log.info("Could not get lock on article. Locked by " + lock.getUsername() + " on " + hostname); JOptionPane.showMessageDialog(this, message, messages.getString("locked_error"), JOptionPane.WARNING_MESSAGE); this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); //Alt. version that keeps select and copy options, for locked view. anArtis.disableAllEditors_butKeepOptionsRelevantToTextCopying(); anArtis.checkForLock(); } else { anArtis.startAutoSaver(); } anArtis.setVisible(true); } else { //not allowed to edit, must do some previewing instead. later. } } void editAction_actionPerformed(ActionEvent e) { if (articleList.hasSelection()) { openArticleInArtis(articleList.getSelectedArticle()); } } void exitAction_actionPerformed(ActionEvent e) { dispose(); } void groupMenuItem_actionPerformed(ActionEvent e) { GroupDialog groupDialog = new GroupDialog(this, articleList.getCurrentGrouper()); groupDialog.pack(); groupDialog.setVisible(true); groupDialog.setVisible(false); Grouper selectedGrouper = groupDialog.getSelectedGrouper(); Comparator selectedComparator = groupDialog.getSelectedComparator(); if (!groupDialog.wasCanceled()) articleList.regroup(selectedGrouper, selectedComparator); validate(); articleList.repaint(); } void prefsMenuItem_actionPerformed(ActionEvent e) { PrefsDialog pd = new PrefsDialog(this, prefs); pd.setVisible(true); if (pd.okResult()) { Properties changed = pd.getChangedPreferences(); Enumeration en = changed.keys(); while (en.hasMoreElements()) { String key = en.nextElement().toString(); String value = changed.getProperty(key); prefs.put(key, value); try { LoginContext.server.savePreference(PREFS_DOMAIN, key, value, LoginContext.sessionKey); } catch (Exception ex) { log.error("Unable to save pref: " + key + "=" + value, ex); } } } } void quitMenuItem_actionPerformed(ActionEvent e) { dispose(); } void articleList_stateChanged(ChangeEvent e) { boolean canEdit = false; try { canEdit = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.EDIT_ARTICLE, articleList.getSelectedArticle().getId(), LoginContext.sessionKey); } catch (RemoteException e1) { log.error("Connection error", e1); } editAction.setEnabled(canEdit); aboutAction.setEnabled(canEdit); printArticleAction.setEnabled(canEdit); changeArticleStatusMenu.setEnabled(canEdit); // All users can publish publishAction.setEnabled(true); // All users can send email sendMailTo.setEnabled(true); // sjekker om brukeren har lov til å slette try { boolean canDelete = LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.LEGACY_DELETE_ARTICLE, articleList.getSelectedArticle().getId(), LoginContext.sessionKey); deleteAction.setEnabled(canDelete); } catch (Exception ex) { log.error("Error check delete privilege", ex); } } void deleteAction_actionPerformed(ActionEvent e) { Article art = articleList.getSelectedArticle(); boolean choice = displayDeleteWarning(); if (choice) { try { if (LoginContext.server.hasArticlePermission(LoginContext.server.getUserID(LoginContext.sessionKey), ArticlePermissions.LEGACY_DELETE_ARTICLE, art.getId(), LoginContext.sessionKey)) { LoginContext.server.deleteArticle(art.getId(), LoginContext.sessionKey); refreshArticles(); } } catch (Exception jeppz) { log.error("Error deleting article", jeppz); } } } void sendMailToJournalistAction_actionPerformed(ActionEvent e) { setCursor(new Cursor(Cursor.WAIT_CURSOR)); Article art = articleList.getSelectedArticle(); String[] replaceWith = new String[8]; try { Person u = LoginContext.server.getSessionUser(LoginContext.sessionKey); replaceWith[0] = u.getName(); replaceWith[1] = u.getEmailAddress(); } catch (java.rmi.RemoteException re) { log.error("Could not get user data from server", re); } replaceWith[2] = art.getJournalist().getName(); replaceWith[3] = art.getJournalist().getEmailAddress(); replaceWith[4] = art.getName(); replaceWith[5] = art.getArticleStatus().getName(); replaceWith[6] = Integer.toString(art.getCurrentNumberOfCharacters()); replaceWith[7] = (art.getPublication() != null) ? art.getPublication().getName() : "Unknown"; String url; try { url = LoginContext.server.getWebXMLRoot(LoginContext.sessionKey); url += "/templates/listermail.template"; } catch (java.rmi.RemoteException re) { log.error("Error getting webxmlroot", re); return; } MailDialog dialog = new MailDialog(this, "", false); dialog.loadTemplate(url, replaceWith); dialog.setFromFieldEditable(false); dialog.setToFieldEditable(true); dialog.pack(); dialog.setVisible(true); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } void publishAction_actionPerformed(ActionEvent e) { if (articleList.hasSelection()) { //fetch a fresh article from the server. In case it has been edited since last refresh of lister Article freshArticle = null; try { freshArticle = LoginContext.server.getArticleByID(articleList.getSelectedArticle().getId(), LoginContext.sessionKey); } catch (Exception ex) { log.error("Could not get article from server!", ex); } PublishDialog pd = new PublishDialog(this, freshArticle); pd.setLastPublishedToDir(lastPublishedToDir); Point p = getLocation(); p.x += 30; p.y += 30; pd.setVisible(true); } } void changeArticleStatus_actionPerformed(ActionEvent e, ArticleStatus status) { Article art = articleList.getSelectedArticle(); if (Artis.isOpen(art)) { JOptionPane.showMessageDialog(this, messages.getString("about_error_long"), messages.getString("about_error"), JOptionPane.ERROR_MESSAGE); return; } setCursor(new Cursor(Cursor.WAIT_CURSOR)); ArticleLock lock = null; try { lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey); } catch (RemoteException re) { log.error("Connection error", re); } boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey); // Is this lock owned by user? boolean isSameUser = false; try { isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername()); } catch (RemoteException re) { log.error("Connection error", re); } if (!lockIsMine && isSameUser) { // The lock is owned by this user, but not this session. Grab lock? String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch (UnknownHostException uhe) { hostname = lock.getHost(); } String rawmessage = messages.getString("hijack_lock_msg"); Object[] args = {hostname}; String message = MessageFormat.format(rawmessage, args); int d = JOptionPane.showConfirmDialog(this, message, messages.getString("hijack_lock_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.YES_OPTION) { try { lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey); } catch (RemoteException rme) { log.error("Connection error", rme); } lockIsMine = true; } if (d == JOptionPane.NO_OPTION) { this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); return; } } if (lockIsMine) { // Everything in order. Change status. try { //It is crusial that we get a fresh copy of the article after we have aquired a write lock art = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey); } catch (Exception e1) { log.error("Sorry could not get a fresh article", e1); JOptionPane.showMessageDialog(this, "Sorry Mac. Could not get articlelock", messages.getString("locked_error"), JOptionPane.ERROR_MESSAGE); return; } art.setArticleStatus(status); boolean saved = false; while (!saved) { try { Article hack = (Article) art.clone(); LoginContext.server.saveArticle(hack, LoginContext.sessionKey); saved = true; } catch (Exception ee) { log.error("Exception saving changed articlestatus", ee); int d = JOptionPane.showConfirmDialog(this, messages.getString("save_error_msg"), messages.getString("save_error_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.NO_OPTION) { saved = true; } } } try { LoginContext.server.releaseArticleLock(art.getId(), LoginContext.sessionKey); } catch (Exception ex) { log.error("Could not release articlelock", ex); } refreshArticles(); } else { String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch (UnknownHostException uhe) { hostname = lock.getHost(); } String user = lock.getUsername(); try { user = LoginContext.server.getUserByUsername(lock.getUsername(), LoginContext.sessionKey).getFullName(); } catch (NoAccessException nae) { log.error("Could not get person holding lock", nae); } String rawmessage = messages.getString("locked_error_long"); Object[] args = {user, hostname}; String message = MessageFormat.format(rawmessage, args); log.info("Could not get lock on article. Locked by {} on {}", lock.getUsername(), hostname); JOptionPane.showMessageDialog(this, message, messages.getString("locked_error"), JOptionPane.ERROR_MESSAGE); } this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } void printArticleAction_actionPerformed(ActionEvent e) { Article article; try { article = LoginContext.server.getArticleByID(articleList.getSelectedArticle().getId(), LoginContext.sessionKey); } catch (RemoteException e1) { log.error("Connection error", e1); return; } if (!article.hasText()) { JOptionPane.showMessageDialog(this, messages.getString("parse_err_edit_art"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE); return; } if (article.getDocument() == null) { if (!article.parseText()) { JOptionPane.showMessageDialog(this, messages.getString("parse_err_contact_adm"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE); return; } } setCursor(new Cursor(Cursor.WAIT_CURSOR)); FOPPrintPublisher fpp = new FOPPrintPublisher(); Properties p = getPrintProperties(); if (p == null) { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); return; } fpp.setTransformerProperties(p); try { fpp.publish(article, null, PublishingMediaEnum.PDF); } catch (Exception ex) { log.error("Error during transformation.", ex); JOptionPane.showMessageDialog(this, messages.getString("transform_error_general"), messages.getString("transform_error_captition"), JOptionPane.ERROR_MESSAGE); } setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } public Properties getPrintProperties() { PrintDialog printDialog = new PrintDialog(this, ResourceBundle.getBundle("org.pegadi.artis.ArtisStrings")); printDialog.pack(); printDialog.setVisible(true); if (!printDialog.wasAccepted()) // Was cancel pressed? return null; return printDialog.getPrintProperties(); } public void updateArticleList() { articleList.revalidate(); articleList.repaint(); } public void setLastPublishedToDir(String lastPublishedToDir) { this.lastPublishedToDir = lastPublishedToDir; } protected void changeArticle(Article art) { if (Artis.isOpen(art)) { JOptionPane.showMessageDialog(this, messages.getString("about_error_long"), messages.getString("about_error"), JOptionPane.ERROR_MESSAGE); return; } this.setCursor(new Cursor(Cursor.WAIT_CURSOR)); ArticleLock lock = null; try { lock = LoginContext.server.getArticleLock(art.getId(), false, LoginContext.sessionKey); } catch (RemoteException re) { log.error("Connection error", re); } boolean lockIsMine = lock.getSessionKey().equals(LoginContext.sessionKey); // Is this lock owned by user? boolean isSameUser = false; try { isSameUser = lock.getUsername().equals(LoginContext.server.getSessionUser(LoginContext.sessionKey).getUsername()); } catch (RemoteException re) { log.error("Connection error", re); } if (!lockIsMine && isSameUser) { // The lock is owned by this user, but not this session. Grab lock? String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch (UnknownHostException uhe) { hostname = lock.getHost(); } String rawmessage = messages.getString("hijack_lock_msg"); Object[] args = {hostname}; String message = MessageFormat.format(rawmessage, args); int d = JOptionPane.showConfirmDialog(this, message, messages.getString("hijack_lock_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.YES_OPTION) { try { lock = LoginContext.server.getArticleLock(art.getId(), true, LoginContext.sessionKey); } catch (RemoteException rme) { log.error("Connection error", rme); } lockIsMine = true; } if (d == JOptionPane.NO_OPTION) { this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); return; } } try { //It is crusial that we get a fresh copy of the article after we have aquired a write lock art = LoginContext.server.getArticleByID(art.getId(), LoginContext.sessionKey); } catch (Exception e1) { log.error("Sorry could not get a fresh article", e1); JOptionPane.showMessageDialog(this, "Sorry Mac. Could not get articlelock", messages.getString("locked_error"), JOptionPane.ERROR_MESSAGE); return; } ArticleDialog artDialog = new ArticleDialog(this, art); artDialog.pack(); artDialog.setLocation(this.getLocation().x + 50, this.getLocation().y + 50); this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if (lockIsMine) { // Everything in order. Change article. artDialog.setVisible(true); setCursor(new Cursor(Cursor.WAIT_CURSOR)); if (artDialog.dialogResult()) { boolean saved = false; while (!saved) { try { Article hack = (Article) artDialog.getArticle().clone(); LoginContext.server.saveArticle(hack, LoginContext.sessionKey); LoginContext.server.setCoJournalistsForArticle(hack.getId(), artDialog.getCoJournalists(), LoginContext.sessionKey); saved = true; } catch (Exception ee) { log.error("Exception saving changed article", ee); int d = JOptionPane.showConfirmDialog(this, messages.getString("save_error_msg"), messages.getString("save_error_caption"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (d == JOptionPane.NO_OPTION) { saved = true; } } } } // Clean up, release articlelock. try { LoginContext.server.releaseArticleLock(art.getId(), LoginContext.sessionKey); } catch (Exception ex) { log.error("Could not release articlelock", ex); } refreshArticles(); } else { // Article locked by someone else. Changing not allowed. String hostname; try { InetAddress address = InetAddress.getByName(lock.getHost()); hostname = address.getHostName(); } catch (UnknownHostException uhe) { hostname = lock.getHost(); } String user = lock.getUsername(); try { user = LoginContext.server.getUserByUsername(lock.getUsername(), LoginContext.sessionKey).getFullName(); } catch (NoAccessException e) { log.error("Could not get person holding lock", e); } String rawmessage = messages.getString("locked_error_preview"); Object[] args = {user, hostname}; String message = MessageFormat.format(rawmessage, args); log.info("Could not get lock on article. Locked by {} on {}", lock.getUsername(), hostname); JOptionPane.showMessageDialog(this, message, messages.getString("locked_error"), JOptionPane.WARNING_MESSAGE); artDialog.disableEditing(); artDialog.setVisible(true); } setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } public void closeAllArtis() { Object[] col = Artis.openArtises.values().toArray(); for (Object aCol : col) { Artis art = (Artis) aCol; try { LoginContext.server.releaseArticleLock(art.getArticle().getId(), LoginContext.sessionKey); } catch (Exception e) { log.error("Error releasing articlelock", e); } art.dispose(); } } void aboutAction_actionPerformed(ActionEvent e) { changeArticle(articleList.getSelectedArticle()); } protected void articleList_actionPerformed(ActionEvent e) { Article art = articleList.getSelectedArticle(); if (e.getID() == 0) { openArticleInArtis(art); } else // "About" if ctrl is down changeArticle(art); } /** * Prints the current list. */ protected void printArticleList() { try { PrinterJob pj = PrinterJob.getPrinterJob(); if (!pj.printDialog()) { log.info("Printing cancelled by user"); return; } TransformerFactory tFactory = TransformerFactory.newInstance(); SAXTransformerFactory factory = (SAXTransformerFactory) tFactory; String url; try { url = LoginContext.server.getWebXMLRoot(LoginContext.sessionKey); url += "/stylesheets/articlelist2fo.xsl"; } catch (java.rmi.RemoteException re) { log.error("Error getting webxmlroot", re); JOptionPane.showMessageDialog(this, messages.getString("parse_err_contact_adm"), messages.getString("parse_err"), JOptionPane.ERROR_MESSAGE); return; } TransformerHandler transformerHandler = factory.newTransformerHandler(new StreamSource(url)); FopFactory fopFactory = FopFactory.newInstance(); FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); FOPPrintRenderer renderer = new FOPPrintRenderer(pj); renderer.setUserAgent(foUserAgent); renderer.setPreviewDialogDisplayed(false); foUserAgent.setRendererOverride(renderer); Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent); transformerHandler.setResult(new SAXResult(fop.getDefaultHandler())); articleList.generateArticleListAsXML(transformerHandler); } catch (Exception e) { log.error("Exception during printing", e); JOptionPane.showMessageDialog(this, messages.getString("print_error"), messages.getString("print_error_caption"), JOptionPane.ERROR_MESSAGE); } } private class ChangeArticleStatusAction extends AbstractAction { private ArticleStatus status; public ChangeArticleStatusAction(ArticleStatus status) { super(status.getName()); this.status = status; } public void actionPerformed(ActionEvent e) { changeArticleStatus_actionPerformed(e, status); } } }