/* * Zettelkasten - nach Luhmann * Copyright (C) 2001-2015 by Daniel Lüdecke (http://www.danielluedecke.de) * * Homepage: http://zettelkasten.danielluedecke.de * * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses/>. * * * Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU * General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben * und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder (wenn Sie möchten) * jeder späteren Version. * * Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein * wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder * der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der * GNU General Public License. * * Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm * erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>. */ package de.danielluedecke.zettelkasten; import com.explodingpixels.macwidgets.BottomBar; import com.explodingpixels.macwidgets.BottomBarSize; import de.danielluedecke.zettelkasten.mac.MacSourceList; import de.danielluedecke.zettelkasten.database.Settings; import de.danielluedecke.zettelkasten.database.AcceleratorKeys; import de.danielluedecke.zettelkasten.database.SearchRequests; import de.danielluedecke.zettelkasten.database.Synonyms; import de.danielluedecke.zettelkasten.util.Tools; import de.danielluedecke.zettelkasten.util.Constants; import de.danielluedecke.zettelkasten.util.classes.DateComparer; import de.danielluedecke.zettelkasten.util.classes.Comparer; import de.danielluedecke.zettelkasten.database.Daten; import com.explodingpixels.macwidgets.MacUtils; import com.explodingpixels.macwidgets.MacWidgetFactory; import com.explodingpixels.macwidgets.UnifiedToolBar; import com.explodingpixels.widgets.TableUtils; import com.explodingpixels.widgets.WindowUtils; import de.danielluedecke.zettelkasten.database.BibTex; import de.danielluedecke.zettelkasten.database.DesktopData; import de.danielluedecke.zettelkasten.mac.MacToolbarButton; import de.danielluedecke.zettelkasten.mac.ZknMacWidgetFactory; import de.danielluedecke.zettelkasten.tasks.TaskProgressDialog; import de.danielluedecke.zettelkasten.util.ColorUtil; import de.danielluedecke.zettelkasten.util.HtmlUbbUtil; import de.danielluedecke.zettelkasten.util.PlatformUtil; import java.awt.AWTKeyStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.GraphicsDevice; import java.awt.IllegalComponentStateException; import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.RowSorter; import javax.swing.border.MatteBorder; import javax.swing.event.HyperlinkEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; import javax.swing.text.AttributeSet; import javax.swing.text.html.HTML; import org.jdesktop.application.Action; /** * * @author danielludecke */ public class SearchResultsFrame extends javax.swing.JFrame { /** * CDaten object, which contains the XML data of the Zettelkasten */ private final Daten dataObj; private final DesktopData desktopObj; /** * A reference to the CSearchRequests-class which stores the searchterms and other * search settings like case-sensitive search, where to search in and so on... */ private final SearchRequests searchrequest; /** * CAccelerator object, which contains the XML data of the accelerator table for the menus */ private final AcceleratorKeys accKeys; /** * Reference to the settings class. */ private final Settings settingsObj; private final BibTex bibtexObj; /** * */ private final Synonyms synonymsObj; /** * Reference to the main frame. */ private final ZettelkastenView mainframe; /** * create a variable for a list model. this list model is used for * the JList-component which displays the keywords of the current * entry. */ private final DefaultListModel keywordListModel = new DefaultListModel(); /** * Indicated whether a table's content is changed, e.g. entries deleted. if so, we have to tell this * the selection listener which - otherwise - would be called several times... */ private boolean tableUpdateActive = false; /** * This variable gets the graphic device and ist needed for full-screen-functionality. see * {@link #viewFullScreen() viewFullScreen()} for more details. */ private final GraphicsDevice graphicdevice = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); private final JFrame searchframe; /** * Returns the table component of the search results window. * @return the table component of the search results window. */ public JTable getSearchFrameTable() { return jTableResults; } /** * get the strings for file descriptions from the resource map */ private final org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class). getContext().getResourceMap(SearchResultsFrame.class); /** * get the strings for file descriptions from the resource map */ private final org.jdesktop.application.ResourceMap toolbarResourceMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class). getContext().getResourceMap(ToolbarIcons.class); /** * * @param zkn * @param d * @param sr * @param desk * @param s * @param ak * @param syn * @param bib */ @SuppressWarnings("LeakingThisInConstructor") public SearchResultsFrame(ZettelkastenView zkn, Daten d, SearchRequests sr, DesktopData desk, Settings s, AcceleratorKeys ak, Synonyms syn, BibTex bib) { searchframe = this; // init variables from parameters dataObj=d; desktopObj=desk; bibtexObj = bib; searchrequest=sr; synonymsObj = syn; accKeys = ak; settingsObj=s; mainframe=zkn; // check whether memory usage is logged. if so, tell logger that new entry windows was opened if (settingsObj.isMemoryUsageLogged) { // log info Constants.zknlogger.log(Level.INFO,"Memory usage logged. Search Results Window opened."); } // create brushed look for window, so toolbar and window-bar become a unit if (settingsObj.isMacAqua()) { MacUtils.makeWindowLeopardStyle(getRootPane()); // WindowUtils.createAndInstallRepaintWindowFocusListener(this); WindowUtils.installJComponentRepainterOnWindowFocusChanged(this.getRootPane()); } // init all components Tools.initLocaleForDefaultActions(org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getActionMap(SearchResultsFrame.class, this)); initComponents(); initListeners(); // remove border, gui-builder doesn't do this initBorders(settingsObj); // set application icon setIconImage(Constants.zknicon.getImage()); // if we have mac os x with aqua, make the window look like typical cocoa-applications if (settingsObj.isMacAqua()) { setupMacOSXLeopardStyle(); } if (settingsObj.isSeaGlass()) { setupSeaGlassStyle(); } // init toggle-items viewMenuHighlight.setSelected(settingsObj.getHighlightSearchResults()); tb_highlight.setSelected(settingsObj.getHighlightSearchResults()); viewMenuShowEntry.setSelected(settingsObj.getShowSearchEntry()); jButtonResetList.setEnabled(false); // init table initTable(); // init combobox. The automatic display-update should be managed // through the combobox's action listener initComboBox(); // init the menu-accelerator table initAcceleratorTable(); initActionMaps(); // This method initialises the toolbar buttons. depending on the user-setting, we either // display small, medium or large icons as toolbar-icons. initToolbarIcons(); // init default sont-sizes initDefaultFontSize(); // and update the title updateTitle(); } /** * */ public final void updateTitle() { String currentTitle = getTitle(); // get filename and find out where extension begins, so we can just set the filename as title File f = settingsObj.getFilePath(); // check whether we have any valid filepath at all if (f!=null && f.exists()) { String fname = f.getName(); // find file-extension int extpos = fname.lastIndexOf(Constants.ZKN_FILEEXTENSION); // set the filename as title if (extpos!=-1) { // show proxy-icon, only applies to mac. getRootPane().putClientProperty("Window.documentFile", f); // set file-name and app-name in title-bar setTitle(currentTitle+"- ["+fname.substring(0,extpos)+"]"); } } } private void initBorders(Settings settingsObj) { /* * Constructor for Matte Border * public MatteBorder(int top, int left, int bottom, int right, Color matteColor) */ jScrollPane1.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorUtil.getBorderGray(settingsObj))); jScrollPane4.setBorder(null); if (settingsObj.getUseMacBackgroundColor() || settingsObj.isMacAqua()) { jListKeywords.setBackground((settingsObj.isMacAqua()) ? ColorUtil.colorJTreeBackground : ColorUtil.colorJTreeLighterBackground); jListKeywords.setForeground(ColorUtil.colorJTreeDarkText); } if (settingsObj.isSeaGlass()) { jPanel3.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, ColorUtil.getBorderGray(settingsObj))); jPanel4.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, ColorUtil.getBorderGray(settingsObj))); jListKeywords.setBorder(ZknMacWidgetFactory.getTitledBorder(resourceMap.getString("jListKeywords.border.title"), settingsObj)); if (settingsObj.getSearchFrameSplitLayout()==JSplitPane.HORIZONTAL_SPLIT) { jPanel1.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, ColorUtil.getBorderGray(settingsObj))); jPanel2.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, ColorUtil.getBorderGray(settingsObj))); } else { jPanel1.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorUtil.getBorderGray(settingsObj))); jPanel2.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, ColorUtil.getBorderGray(settingsObj))); } // jPanel3.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, ColorUtil.getBorderGray(settingsObj))); } if (settingsObj.isMacAqua()) { ZknMacWidgetFactory.updateSplitPane(jSplitPaneSearch1); ZknMacWidgetFactory.updateSplitPane(jSplitPaneSearch2); jListKeywords.setBorder(ZknMacWidgetFactory.getTitledBorder(resourceMap.getString("jListKeywords.border.title"), ColorUtil.colorJTreeText, settingsObj)); } } /** * This method initialises the toolbar buttons. depending on the user-setting, we either * display small, medium or large icons as toolbar-icons. */ public final void initToolbarIcons() { // check whether the toolbar should be displayed at all... if (!settingsObj.getShowIcons() && !settingsObj.getShowIconText()) { // if not, hide it and leave. searchToolbar.setVisible(false); // and set a border to the main panel, because the toolbar's dark border is hidden // and remove border from the main panel searchMainPanel.setBorder(new MatteBorder(1,0,0,0,ColorUtil.colorDarkLineGray)); return; } // set toolbar visible searchToolbar.setVisible(true); // and remove border from the main panel searchMainPanel.setBorder(null); // init toolbar button array javax.swing.JButton toolbarButtons[] = new javax.swing.JButton[] { tb_copy, tb_selectall, tb_editentry, tb_remove, tb_manlinks, tb_luhmann, tb_bookmark, tb_desktop, tb_highlight }; String[] buttonNames = new String[] { "tb_copyText", "tb_selectallText", "tb_editText", "tb_deleteText", "tb_addmanlinksText", "tb_addluhmannText", "tb_addbookmarkText", "tb_addtodesktopText", "tb_highlightText" }; String[] iconNames = new String[] { "copyIcon", "selectAllIcon", "editEntryIcon", "deleteIcon", "addManLinksIcon", "addLuhmannIcon", "addBookmarksIcon", "addDesktopIcon", "highlightKeywordsIcon" }; // set toolbar-icons' text if (settingsObj.getShowIconText()) { for (int cnt=0; cnt< toolbarButtons.length; cnt++) { toolbarButtons[cnt].setText(toolbarResourceMap.getString(buttonNames[cnt])); } } else { for (javax.swing.JButton tbb : toolbarButtons) { tbb.setText(""); } } // show icons, if requested if (settingsObj.getShowIcons()) { // retrieve icon theme path String icontheme = settingsObj.getIconThemePath(); for (int cnt=0; cnt< toolbarButtons.length; cnt++) { toolbarButtons[cnt].setIcon(new ImageIcon(ZettelkastenView.class.getResource(icontheme+toolbarResourceMap.getString(iconNames[cnt])))); } } else { for (javax.swing.JButton tbb : toolbarButtons) { tbb.setIcon(null); } } if (settingsObj.isMacAqua()) makeMacToolBar(); if (settingsObj.isSeaGlass()) makeSeaGlassToolbar(); } private void setupSeaGlassStyle() { getRootPane().setBackground(ColorUtil.colorSeaGlassGray); jTextFieldFilterList.putClientProperty("JTextField.variant", "search"); jEditorPaneSearchEntry.setBackground(Color.white); jButtonDeleteSearch.setBorderPainted(true); jButtonDeleteSearch.putClientProperty("JButton.buttonType","textured"); } /** * This method applies some graphical stuff so the appearance of the program is even more * mac-like... */ private void setupMacOSXLeopardStyle() { // now we have to change back the background-color of all components in the mainpart of the // frame, since the brush-metal-look applies to all components // // other components become normal gray - which is, however, a little bit // darker than the default gray // // since snow-leopard has a different color-rendering, we need a different // background-color for OS X 10.6 Color backcol = ColorUtil.getMacBackgroundColor(); // on Leopard (OS X 10.5), we have different rendering, thus we need these lines if (PlatformUtil.isLeopard()) { searchframe.getContentPane().setBackground(backcol); searchMainPanel.setBackground(backcol); } jPanel1.setBackground(backcol); jPanel2.setBackground(backcol); jPanel3.setBackground(backcol); jPanel4.setBackground(backcol); jSplitPaneSearch1.setBackground(backcol); jSplitPaneSearch2.setBackground(backcol); jTextFieldFilterList.putClientProperty("JTextField.variant", "search"); MacWidgetFactory.makeEmphasizedLabel(jLabel1); MacWidgetFactory.makeEmphasizedLabel(jLabelHits); } private void makeSeaGlassToolbar() { Tools.makeTexturedToolBarButton(tb_copy, Tools.SEGMENT_POSITION_FIRST); Tools.makeTexturedToolBarButton(tb_selectall, Tools.SEGMENT_POSITION_LAST); Tools.makeTexturedToolBarButton(tb_editentry, Tools.SEGMENT_POSITION_FIRST); Tools.makeTexturedToolBarButton(tb_remove, Tools.SEGMENT_POSITION_LAST); Tools.makeTexturedToolBarButton(tb_manlinks, Tools.SEGMENT_POSITION_FIRST); Tools.makeTexturedToolBarButton(tb_luhmann, Tools.SEGMENT_POSITION_MIDDLE); if (settingsObj.getShowAllIcons()) { Tools.makeTexturedToolBarButton(tb_bookmark, Tools.SEGMENT_POSITION_MIDDLE); Tools.makeTexturedToolBarButton(tb_desktop, Tools.SEGMENT_POSITION_LAST); } else { Tools.makeTexturedToolBarButton(tb_bookmark, Tools.SEGMENT_POSITION_LAST); } Tools.makeTexturedToolBarButton(tb_highlight, Tools.SEGMENT_POSITION_ONLY); searchToolbar.setPreferredSize(new java.awt.Dimension(searchToolbar.getSize().width,Constants.seaGlassToolbarHeight)); searchToolbar.add(new javax.swing.JToolBar.Separator(), 0); } private void makeMacToolBar() { // hide default toolbr searchToolbar.setVisible(false); this.remove(searchToolbar); // and create mac toolbar if (settingsObj.getShowIcons() || settingsObj.getShowIconText()) { UnifiedToolBar mactoolbar = new UnifiedToolBar(); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_copy, MacToolbarButton.SEGMENT_POSITION_FIRST)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_selectall, MacToolbarButton.SEGMENT_POSITION_LAST)); mactoolbar.addComponentToLeft(MacWidgetFactory.createSpacer(16, 1)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_editentry, MacToolbarButton.SEGMENT_POSITION_FIRST)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_remove, MacToolbarButton.SEGMENT_POSITION_LAST)); mactoolbar.addComponentToLeft(MacWidgetFactory.createSpacer(16, 1)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_manlinks, MacToolbarButton.SEGMENT_POSITION_FIRST)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_luhmann, MacToolbarButton.SEGMENT_POSITION_MIDDLE)); if (settingsObj.getShowAllIcons()) { mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_bookmark, MacToolbarButton.SEGMENT_POSITION_MIDDLE)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_desktop, MacToolbarButton.SEGMENT_POSITION_LAST)); } else { mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_bookmark, MacToolbarButton.SEGMENT_POSITION_LAST)); } mactoolbar.addComponentToLeft(MacWidgetFactory.createSpacer(16, 1)); mactoolbar.addComponentToLeft(MacToolbarButton.makeTexturedToolBarButton(tb_highlight, MacToolbarButton.SEGMENT_POSITION_ONLY)); mactoolbar.installWindowDraggerOnWindow(this); searchMainPanel.add(mactoolbar.getComponent(),BorderLayout.PAGE_START); } makeMacBottomBar(); } private void makeMacBottomBar() { jPanel9.setVisible(false); BottomBar macbottombar = new BottomBar(BottomBarSize.LARGE); macbottombar.addComponentToLeft(MacWidgetFactory.makeEmphasizedLabel(jLabelHits),20); macbottombar.addComponentToLeft(MacWidgetFactory.makeEmphasizedLabel(jLabel1),4); macbottombar.addComponentToLeft(jComboBoxSearches,4); macbottombar.addComponentToLeft(jButtonDeleteSearch,4); jButtonDeleteSearch.setBorderPainted(true); jButtonDeleteSearch.putClientProperty("JButton.buttonType","textured"); searchStatusPanel.remove(jPanel9); searchStatusPanel.setBorder(null); searchStatusPanel.setLayout(new BorderLayout()); searchStatusPanel.add(macbottombar.getComponent(),BorderLayout.PAGE_START); } /** * This method sets the default font-size for tables, lists and treeviews. If the * user wants to have bigger font-sizes for better viewing, the new font-size will * be applied to the components here. */ private void initDefaultFontSize() { // get the default fontsize for tables and lists int defaultsize = settingsObj.getTableFontSize(); // get current font int fsize = jTableResults.getFont().getSize(); // retrieve default listvewfont Font defaultfont = settingsObj.getTableFont(); // create new font, add fontsize-value Font f = new Font(defaultfont.getName(), defaultfont.getStyle(), fsize+defaultsize); // set new font jTableResults.setFont(f); // set new font jListKeywords.setFont(f); } private void initListeners() { // these codelines add an escape-listener to the dialog. so, when the user // presses the escape-key, the same action is performed as if the user // presses the cancel button... KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); ActionListener cancelAction = new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { quitFullScreen(); } }; getRootPane().registerKeyboardAction(cancelAction, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); // these codelines add an escape-listener to the dialog. so, when the user // presses the escape-key, the same action is performed as if the user // presses the cancel button... stroke = KeyStroke.getKeyStroke(accKeys.getAcceleratorKey(AcceleratorKeys.MAINKEYS, "showDesktopWindow")); ActionListener showDesktopWindowAction = new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mainframe.showDesktopWindow(); } }; getRootPane().registerKeyboardAction(showDesktopWindowAction, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); // these codelines add an escape-listener to the dialog. so, when the user // presses the escape-key, the same action is performed as if the user // presses the cancel button... stroke = KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0); ActionListener showMainFrameAction = new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mainframe.bringToFront(); } }; getRootPane().registerKeyboardAction(showMainFrameAction, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); // these codelines add an escape-listener to the dialog. so, when the user // presses the escape-key, the same action is performed as if the user // presses the cancel button... stroke = KeyStroke.getKeyStroke(accKeys.getAcceleratorKey(AcceleratorKeys.MAINKEYS, "showNewEntryWindow")); ActionListener showNewEntryFrameAction = new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mainframe.showNewEntryWindow(); } }; getRootPane().registerKeyboardAction(showNewEntryFrameAction, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); searchSearchMenu.addMenuListener(new javax.swing.event.MenuListener() { @Override public void menuSelected(javax.swing.event.MenuEvent evt) { setListSelected(jListKeywords.getSelectedIndex()!=-1); String t1 = jEditorPaneSearchEntry.getSelectedText(); setTextSelected(t1!=null && !t1.isEmpty()); } @Override public void menuDeselected(javax.swing.event.MenuEvent evt) {} @Override public void menuCanceled(javax.swing.event.MenuEvent evt) {} }); jEditorPaneSearchEntry.addHyperlinkListener(new javax.swing.event.HyperlinkListener() { @Override public void hyperlinkUpdate(javax.swing.event.HyperlinkEvent evt) { // get input event with additional modifiers java.awt.event.InputEvent inev = evt.getInputEvent(); // check whether shift key was pressed, and if so, remove manual link if (inev.isControlDown() || inev.isMetaDown()) { // get selected entry int row = jTableResults.getSelectedRow(); // when we have a valid selection, go on if (row!=-1) { int displayedZettel = Integer.parseInt(jTableResults.getValueAt(row, 0).toString()); if (Tools.removeHyperlink(evt.getDescription(), dataObj, displayedZettel)) { mainframe.updateDisplay(); } } } else if (evt.getEventType() == HyperlinkEvent.EventType.ENTERED) { javax.swing.text.Element elem = evt.getSourceElement(); if (elem != null) { AttributeSet attr = elem.getAttributes(); AttributeSet a = (AttributeSet) attr.getAttribute(HTML.Tag.A); if (a != null) { jEditorPaneSearchEntry.setToolTipText((String) a.getAttribute(HTML.Attribute.TITLE)); } } } else if (evt.getEventType() == HyperlinkEvent.EventType.EXITED) { jEditorPaneSearchEntry.setToolTipText(null); } else { openAttachment(evt); } } }); jTableResults.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mouseClicked(java.awt.event.MouseEvent evt) { // this listener should only react on left-mouse-button-clicks... // if other button then left-button clicked, don't count it. if(evt.getButton()!=MouseEvent.BUTTON1) return; // only show entry on double clicl if (2==evt.getClickCount()) displayEntryInMainframe(); } }); jTextFieldFilterList.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyReleased(java.awt.event.KeyEvent evt) { if (Tools.isNavigationKey(evt.getKeyCode())) { // if user pressed navigation key, select next table entry de.danielluedecke.zettelkasten.util.TableUtils.navigateThroughList(jTableResults, evt.getKeyCode()); } else { // select table-entry live, while the user is typing... de.danielluedecke.zettelkasten.util.TableUtils.selectByTyping(jTableResults,jTextFieldFilterList,1); } } }); // // Now come the mouse-listeners // // here we set up a popup-trigger for the jListEntryKeywords and how this component // should react on mouse-clicks. a single click filters the jTableLinks, a double-click // starts a keyword-search jListKeywords.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mouseClicked(java.awt.event.MouseEvent evt) { // this listener should only react on left-mouse-button-clicks... // if other button then left-button clicked, leeave... if(evt.getButton()!=MouseEvent.BUTTON1) return; // on double click if (2==evt.getClickCount()) { if (jListKeywords.getSelectedIndex()!=-1) newSearchFromKeywordsLogOr(); } // on single click... if (1==evt.getClickCount()) { highlightSegs(); } } }); jListKeywords.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyReleased(java.awt.event.KeyEvent evt) { // if a navigation-key (arrows, page-down/up, home etc.) is pressed, // we assume a new item-selection, so behave like on a mouse-click and // filter the links if (Tools.isNavigationKey(evt.getKeyCode())) { highlightSegs(); } } }); } /** * This method inits the action map for several components like the tables, the treeviews * or the lists. here we can associate certain keystrokes with related methods. e.g. hitting * the enter-key in a table shows (activates) the related entry. * <br><br> * Setting up action maps gives a better overview and is shorter than adding key-release-events * to all components, although key-events would fulfill the same purpose. * <br><br> * The advantage of action maps is, that dependent from the operating system we need only * to associte a single action. with key-events, for each component we have to check * whether the operating system is mac os or windows, and then checking for different keys, * thus doubling each command: checking for F2 to edit, or checking for command+enter and also * call the edit-method. using action maps, we simply as for the os once, storing the related * keystroke-value as string, and than assign this string-value to the components. */ private void initActionMaps() { // <editor-fold defaultstate="collapsed" desc="Init of action-maps so we have shortcuts for the tables"> // create action which should be executed when the user presses // the enter-key AbstractAction a_enter = new AbstractAction(){ @Override public void actionPerformed(ActionEvent e) { if (jTextFieldFilterList==e.getSource()) filterResultList(); if (jTableResults==e.getSource()) displayEntryInMainframe(); } }; // put action to the tables' actionmaps jTextFieldFilterList.getActionMap().put("EnterKeyPressed",a_enter); jTableResults.getActionMap().put("EnterKeyPressed",a_enter); // associate enter-keystroke with that action KeyStroke ks = KeyStroke.getKeyStroke("ENTER"); jTextFieldFilterList.getInputMap().put(ks, "EnterKeyPressed"); jTableResults.getInputMap().put(ks, "EnterKeyPressed"); // </editor-fold> } private void highlightSegs() { // and highlight text segments if (settingsObj.getHighlightSegments()) { int[] selectedValues = getSelectedEntriesFromTable(); if (selectedValues!=null && selectedValues.length>0) { displayZettelContent(selectedValues[0],null); } } } /** * This method sets the accelerator table for all relevant actions which should have * accelerator keys. We don't use the GUI designer to set the values, because the user * should have the possibility to define own accelerator keys, which are managed * within the CAcceleratorKeys-class and loaed/saved via the CSettings-class */ private void initAcceleratorTable() { // setting up the accelerator table. we have two possibilities: either assigning // accelerator keys directly with an action like this: // // javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(zettelkasten.ZettelkastenApp.class).getContext().getActionMap(ZettelkastenView.class, this); // AbstractAction ac = (AbstractAction) actionMap.get("newEntry"); // KeyStroke controlN = KeyStroke.getKeyStroke("control N"); // ac.putValue(AbstractAction.ACCELERATOR_KEY, controlN); // // or setting the accelerator key directly to a menu-item like this: // // newEntryMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.META_MASK)); // // we choose the first option, because so we can easily iterate through the xml file // and retrieve action names as well as accelerator keys. this saves a lot of typing work here // // get the action map javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class). getContext().getActionMap(SearchResultsFrame.class, this); // iterate the xml file with the accelerator keys for the main window for (int cnt=1; cnt<=accKeys.getCount(AcceleratorKeys.SEARCHRESULTSKEYS); cnt++) { // get the action's name String actionname = accKeys.getAcceleratorAction(AcceleratorKeys.SEARCHRESULTSKEYS, cnt); // check whether we have found any valid action name if (actionname!=null && !actionname.isEmpty()) { // retrieve action AbstractAction ac = (AbstractAction) actionMap.get(actionname); // get the action's accelerator key String actionkey = accKeys.getAcceleratorKey(AcceleratorKeys.SEARCHRESULTSKEYS, cnt); // check whether we have any valid actionkey if (actionkey!=null && !actionkey.isEmpty()) { // retrieve keystroke setting KeyStroke ks = KeyStroke.getKeyStroke(actionkey); // and put them together :-) ac.putValue(AbstractAction.ACCELERATOR_KEY, ks); } } } // now set the mnemonic keys of the menus (i.e. the accelerator keys, which give access // to the menu via "alt"+key). since the menus might have different texts, depending on // the programs language, we retrieve the menu text and simply set the first char // as mnemonic key // ATTENTION! Mnemonic keys are NOT applied on Mac OS, see Apple guidelines for // further details: // http://developer.apple.com/DOCUMENTATION/Java/Conceptual/Java14Development/07-NativePlatformIntegration/NativePlatformIntegration.html#//apple_ref/doc/uid/TP40001909-211867-BCIBDHFJ if (!settingsObj.isMacAqua()) { // init the variables String menutext; char mkey; // the mnemonic key for the file menu menutext = searchFileMenu.getText(); mkey = menutext.charAt(0); searchFileMenu.setMnemonic(mkey); // the mnemonic key for the edit menu menutext = searchEditMenu.getText(); mkey = menutext.charAt(0); searchEditMenu.setMnemonic(mkey); // the mnemonic key for the filter menu menutext = searchFilterMenu.getText(); mkey = menutext.charAt(0); searchFilterMenu.setMnemonic(mkey); // the mnemonic key for the search menu menutext = searchSearchMenu.getText(); mkey = menutext.charAt(0); searchSearchMenu.setMnemonic(mkey); // the mnemonic key for the view menu menutext = searchViewMenu.getText(); mkey = menutext.charAt(0); searchViewMenu.setMnemonic(mkey); } // on Mac OS, at least for the German locale, the File menu is called different // compared to windows or linux. Furthermore, we don't need the about and preferences // menu items, since these are locates on the program's menu item in the apple-menu-bar if (PlatformUtil.isMacOS()) searchFileMenu.setText(resourceMap.getString("macFileMenuText")); // en- or disable fullscreen icons setFullScreenSupp(graphicdevice.isFullScreenSupported()); // if fullscreen is not supportet, tell this in the tooltip if (!graphicdevice.isFullScreenSupported()) { AbstractAction ac = (AbstractAction) actionMap.get("viewFullScreen"); ac.putValue(AbstractAction.SHORT_DESCRIPTION,resourceMap.getString("fullScreenNotSupported")); } } /** * This option toggles the setting, whether a selected entry from the search results should also * immediately be displayed in the main frame or not. */ @Action public void showEntryImmediately() { settingsObj.setShowSearchEntry(!settingsObj.getShowSearchEntry()); } @Action public void resetResultslist() { prepareResultList(jComboBoxSearches.getSelectedIndex()); // set inputfocus to the table, so key-navigation can start immediately jTableResults.requestFocusInWindow(); // finally, select first entry try { jTableResults.setRowSelectionInterval(0, 0); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } // enable refresh button jButtonResetList.setEnabled(false); } private void filterResultList() { // when we filter the table and want to restore it, we don't need to run the // time-consuming task that creates the author-list and related author-frequencies. // instead, we simply copy the values from the linkedlist to the table-model, which is // much faster. but therefore we have to apply all changes to the filtered-table // (like adding/changing values in a filtered list) to the linked list as well. // get text from the textfield containing the filter string // convert to lowercase, we don't want case-sensitive search String text = jTextFieldFilterList.getText().toLowerCase(); // tell selection listener to do nothing... tableUpdateActive = true; // when we have no text, do nothing if (!text.isEmpty()) { // get table model DefaultTableModel dtm = (DefaultTableModel)jTableResults.getModel(); // go through table and delete all rows that don't contain the filter text for (int cnt=(jTableResults.getRowCount()-1); cnt>=0; cnt--) { // retrieve row-index from the model int rowindex = jTableResults.convertRowIndexToModel(cnt); // get the string (author) value from the table // convert to lowercase, we don't want case-sensitive search String value = dtm.getValueAt(rowindex, 1).toString().toLowerCase(); // in case we have the jTableTitles, we also add the timestamps and rating-values to the filter-value // so we can also filter entries according to their timestamp value = value+dtm.getValueAt(rowindex, 2).toString()+dtm.getValueAt(rowindex, 3).toString()+dtm.getValueAt(rowindex, 4).toString(); // check for regex pattern if (text.contains("?")) { try { // replace all "?" into . String dummy = text.replace("?", "."); // in case the user wanted to search for ?, replace \. into \?. dummy = dummy.replace("\\.", "\\?").toLowerCase(); // create regex pattern Pattern pattern = Pattern.compile(dummy); // now check whether pattern exists in value Matcher matcher = pattern.matcher(value); // if the text is *not* part of the column, delete that row if (!matcher.find()) { dtm.removeRow(rowindex); } } catch (PatternSyntaxException ex) { // in case of invalid regex, simply try to find the usual pattern if (!value.contains(text)) dtm.removeRow(rowindex); } } // if the text is *not* part of the column, delete that row else if (!value.contains(text)) dtm.removeRow(rowindex); } // reset textfield jTextFieldFilterList.setText(""); jTextFieldFilterList.requestFocusInWindow(); // enable textfield only if we have more than 1 element in the jtable jTextFieldFilterList.setEnabled(jTableResults.getRowCount()>0); // enable refresh button jButtonResetList.setEnabled(true); // create a new stringbuilder to prepare the label // that shows the amount of found entries StringBuilder sb = new StringBuilder(""); sb.append("("); sb.append(String.valueOf(dtm.getRowCount())); sb.append(" "); sb.append(resourceMap.getString("hitsText")); sb.append(")"); // set labeltext jLabelHits.setText(sb.toString()); } // tell selection listener action is possible again... tableUpdateActive = false; } /** * This option toggles the setting whether search terms should be highlighted or not. */ @Action public void toggleHighlightResults() { // check whether highlighting is activated if (!settingsObj.getHighlightSearchResults()) { // if not, activate it settingsObj.setHighlightSearchResults(true); } else { // nex, if highlighting is activated, // check whether whole word highlighting is activated if (!settingsObj.getHighlightWholeWordSearch()) { // if not, activate whole-word-highlighting and do not // deactivate general highlighting settingsObj.setHighlightWholeWordSearch(true); } // else if both were activated, deactivate all else { settingsObj.setHighlightSearchResults(false); settingsObj.setHighlightWholeWordSearch(false); } } updateDisplay(); } @Action public void addKeywordsToEntries() { // create linked list as parameter for filter-dialog LinkedList<String> keywords = new LinkedList<>(); // go through all keyword-entries for (int cnt=1; cnt<=dataObj.getCount(Daten.KWCOUNT); cnt++) { // get keyword String k = dataObj.getKeyword(cnt); // add it to list if (!k.isEmpty()) keywords.add(k); } // if dialog window isn't already created, do this now if (null == filterSearchDlg) { // create a new dialog window filterSearchDlg = new CFilterSearch(this,settingsObj,keywords,resourceMap.getString("addKeywordsToEntriesTitle"),false); // center window filterSearchDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(filterSearchDlg); // when we have any selected keywords, go on and add them all to all the selected // entries in the search result if (filterSearchDlg.getFilterTerms()!=null) { // get all selected entries int[] entries = getSelectedEntriesFromTable(); // go through all selected entries // now iterate the chosen keywords // and add each keyword to all selected entries for (int e : entries) dataObj.addKeywordsToEntry(filterSearchDlg.getFilterTerms(), e, 1); // keyword-list is not up-to-date dataObj.setKeywordlistUpToDate(false); // update the display updateDisplay(); } // dispose window... filterSearchDlg.dispose(); filterSearchDlg = null; } @Action public void switchLayout() { int currentlayout = settingsObj.getSearchFrameSplitLayout(); if (JSplitPane.HORIZONTAL_SPLIT == currentlayout) { currentlayout = JSplitPane.VERTICAL_SPLIT; if (settingsObj.isSeaGlass()) { jPanel1.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, ColorUtil.getBorderGray(settingsObj))); jPanel2.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, ColorUtil.getBorderGray(settingsObj))); } } else { currentlayout = JSplitPane.HORIZONTAL_SPLIT; if (settingsObj.isSeaGlass()) { jPanel1.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, ColorUtil.getBorderGray(settingsObj))); jPanel2.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, ColorUtil.getBorderGray(settingsObj))); } } settingsObj.setSearchFrameSplitLayout(currentlayout); jSplitPaneSearch1.setOrientation(currentlayout); if (settingsObj.isMacAqua()) ZknMacWidgetFactory.updateSplitPane(jSplitPaneSearch1); } @Action public void showEntryInDesktop() { // get selected row int row = jTableResults.getSelectedRow(); // check for valid value if (row!=-1) { try { int nr = Integer.parseInt(jTableResults.getValueAt(row, 0).toString()); if (desktopObj.isEntryInAnyDesktop(nr)) { mainframe.showEntryInDesktopWindow(nr); } } catch (NumberFormatException ex) { } } } @Action public void addAuthorsToEntries() { // create linked list as parameter for filter-dialog LinkedList<String> suthors = new LinkedList<>(); // go through all author-entries for (int cnt=1; cnt<=dataObj.getCount(Daten.AUCOUNT); cnt++) { // get authors String a = dataObj.getAuthor(cnt); // add it to list if (!a.isEmpty()) suthors.add(a); } // if dialog window isn't already created, do this now if (null == filterSearchDlg) { // create a new dialog window filterSearchDlg = new CFilterSearch(this,settingsObj,suthors,resourceMap.getString("addAuthorsToEntriesTitle"),false); // center window filterSearchDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(filterSearchDlg); // when we have any selected keywords, go on and add them all to all the selected // entries in the search result if (filterSearchDlg.getFilterTerms()!=null) { // get all selected entries int[] entries = getSelectedEntriesFromTable(); // go through all selected entries for (int e : entries) { // now iterate the chosen authors // and add each author to all selected entries for (String a : filterSearchDlg.getFilterTerms()) dataObj.addAuthorToEntry(a, e, 1); } // author-list is not up-to-date dataObj.setAuthorlistUpToDate(false); // update the display updateDisplay(); } // dispose window... filterSearchDlg.dispose(); filterSearchDlg = null; } /** * This method inits the combo-boxes, i.e. filling it with search-result-entries * and setting up an action listener. The action-listener will update the jTableResults * with the search-result-entrynumbers and update the display (filling the textfields). */ private void initComboBox() { // clear combobox jComboBoxSearches.removeAllItems(); for (int cnt=0; cnt<searchrequest.getCount(); cnt++) { jComboBoxSearches.addItem(searchrequest.getShortDescription(cnt)); } // add action listener to combo box jComboBoxSearches.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { // set all results, i.e. all entry-numbers and the entries' titles, into the search result table prepareResultList(jComboBoxSearches.getSelectedIndex()); // and update the display, i.e. show the entry's content updateDisplay(); // finally, select first entry try { jTableResults.setRowSelectionInterval(0, 0); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } // set inputfocus to the table, so key-navigation can start immediately jTableResults.requestFocusInWindow(); } }); try { // select first item jComboBoxSearches.setSelectedIndex(0); } catch (IllegalArgumentException ex) { // log error Constants.zknlogger.log(Level.SEVERE,ex.getLocalizedMessage()); } } /** * This method initializes the table.<br><br> * - it puts the tab-key as new traversal-key<br> * - sets the autosorter<br> * - displayes the cellgrid<br> * - implements action- and selection-listeners */ private void initTable() { // usually, the tab key selects the next cell in a jTable. here we override this // setting, changing the tab-key to change the focus. // bind our new forward focus traversal keys Set<AWTKeyStroke> newForwardKeys = new HashSet<>(1); newForwardKeys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,0)); jTableResults.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,Collections.unmodifiableSet(newForwardKeys)); // bind our new backward focus traversal keys Set<AWTKeyStroke> newBackwardKeys = new HashSet<>(1); newBackwardKeys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB,KeyEvent.SHIFT_MASK+KeyEvent.SHIFT_DOWN_MASK)); jTableResults.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,Collections.unmodifiableSet(newBackwardKeys)); // create new table sorter TableRowSorter<TableModel> sorter = new TableRowSorter<>(); // tell tgis jtable that it has an own sorter jTableResults.setRowSorter(sorter); // and tell the sorter, which table model to sort. sorter.setModel((DefaultTableModel)jTableResults.getModel()); // in this table, the first column needs a custom comparator. try { // sorter for titles sorter.setComparator(1,new Comparer()); // sorter for desktop names sorter.setComparator(5,new Comparer()); // this table has two more columns that should be sorted, the columns with // the entries timestamps. sorter.setComparator(2,new DateComparer()); sorter.setComparator(3,new DateComparer()); } catch (IndexOutOfBoundsException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } // get last table sorting RowSorter.SortKey sk = settingsObj.getTableSorting(jTableResults); // any sorting found? if (sk != null) { // create array with sort key ArrayList l = new ArrayList(); l.add(sk); // set sort key to table sorter.setSortKeys(l); // sort table sorter.sort(); } // make extra table-sorter for itunes-tables if (settingsObj.isMacAqua()) { TableUtils.SortDelegate sortDelegate = new TableUtils.SortDelegate() { @Override public void sort(int columnModelIndex, TableUtils.SortDirection sortDirection) { } }; TableUtils.makeSortable(jTableResults, sortDelegate); // change back default column-resize-behaviour when we have itunes-tables, // since the default for those is "auto resize off" jTableResults.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); } jTableResults.setShowHorizontalLines(settingsObj.getShowGridHorizontal()); jTableResults.setShowVerticalLines(settingsObj.getShowGridVertical()); jTableResults.setIntercellSpacing(settingsObj.getCellSpacing()); jTableResults.getTableHeader().setReorderingAllowed(false); // if the user wants to see grids, we need to change the gridcolor on mac-aqua jTableResults.setGridColor(settingsObj.getTableGridColor()); SelectionListener listener = new SelectionListener(jTableResults); jTableResults.getSelectionModel().addListSelectionListener(listener); jTableResults.getColumnModel().getSelectionModel().addListSelectionListener(listener); } /** * This method updates the combobox, when new search results are added or former * search requests are deleted. therefor, we have to temporarily remove the action listener, * because changing the combobox-content would fire several actions, which may interfer with * our updating-process * @param selectedrow here we can pass a table row that should be selected after updating the combo-box. * use "0" to select the first entry in the table, "-1" to select the last selection (if any) or any * other value. * @param searchnr the number of the searchrequest that should be displayed. use "-1" to show the default * search-request, which is either the currently used search-request, or - if it was deleted - the last search * request. use any other number for a specific search request. */ public void updateComboBox(int selectedrow, int searchnr) { // init variable int selection; // check whether we have any parameter if (searchnr!=-1) selection = searchnr; // remember current selection for later use, see below else selection = jComboBoxSearches.getSelectedIndex(); // used for tablerowselection int row; // if we have a parameter for row-selection, set it here if (selectedrow!=-1) row = selectedrow; // remember selected row... else row = jTableResults.getSelectedRow(); // get all action listeners from the combo box ActionListener[] al = jComboBoxSearches.getActionListeners(); // remove all action listeners so we don't fire several action-events // when we update the combo box. we can set the action listener later again for (ActionListener listener : al) jComboBoxSearches.removeActionListener(listener); // clear combobox jComboBoxSearches.removeAllItems(); // add search descriptions to combobox for (int cnt=0; cnt<searchrequest.getCount(); cnt++) jComboBoxSearches.addItem(searchrequest.getShortDescription(cnt)); // add action listener to combo box jComboBoxSearches.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(ActionEvent evt) { // set all results, i.e. all entry-numbers and the entries' titles, into the search result table prepareResultList(jComboBoxSearches.getSelectedIndex()); // and update the display, i.e. show the entry's content updateDisplay(); // set inputfocus to the table, so key-navigation can start immediately jTableResults.requestFocusInWindow(); // finally, select first entry try { jTableResults.setRowSelectionInterval(0, 0); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } } }); // if we have any searchrequests at all, go on here if (searchrequest.getCount()>0) { // check whether the last selected searchrequest is still available // if not, choose the last search request in the combobox... if (selection!=searchrequest.getCurrentSearch()) selection = jComboBoxSearches.getItemCount()-1; // select search request jComboBoxSearches.setSelectedIndex(selection); // if we had no prevous selection, set row-selector to first item. if (-1==row) row = 0; // if the selected row was the last value, set row-counter to last row else if (row>=jTableResults.getRowCount()) row = jTableResults.getRowCount()-1; // finally... try { // select the appropriate table-entry jTableResults.setRowSelectionInterval(row, row); // and make sure it is visible... jTableResults.scrollRectToVisible(jTableResults.getCellRect(row,0,false)); } catch (IllegalArgumentException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } } // make window invisible else { setVisible(false); // and disable hotkey mainframe.setSearchResultsAvailable(false); } } /** * This method retrieves the result-entry-numbers from a search request "nr" and fills * the jTableResult with those entry-numbers and the entries' related titles. * * @param searchrequestnr the search request of which we want to display the search results. */ private void prepareResultList(int searchrequestnr) { // get search results int[] result = searchrequest.getSearchResults(searchrequestnr); // save current search request number searchrequest.setCurrentSearch(searchrequestnr); // check whether we have any results if (result!=null) { // tell selection listener to do nothing... tableUpdateActive = true; // sort the array with the entry-numbers of the search result if (result.length>0) Arrays.sort(result); // get the table model DefaultTableModel dtm = (DefaultTableModel)jTableResults.getModel(); // clear table dtm.setRowCount(0); // iterate the result-array for (int cnt=0; cnt<result.length; cnt++) { // create a new object Object[] ob = new Object[6]; // store the information in that object // first the entry number ob[0] = result[cnt]; // then the entry's title ob[1] = dataObj.getZettelTitle(result[cnt]); // get timestamp String[] timestamp = dataObj.getTimestamp(result[cnt]); // init timestamp variables. String created = ""; String edited = ""; // check whether we have any timestamp at all. if (timestamp!=null && !timestamp[0].isEmpty() && timestamp[0].length()>=6) created = timestamp[0].substring(4,6)+"."+timestamp[0].substring(2,4)+".20"+timestamp[0].substring(0,2); // check whether we have any timestamp at all. if (timestamp!=null && !timestamp[1].isEmpty() && timestamp[1].length()>=6) edited = timestamp[1].substring(4,6)+"."+timestamp[1].substring(2,4)+".20"+timestamp[1].substring(0,2); ob[2] = created; ob[3] = edited; // now, the entry's rating ob[4] = dataObj.getZettelRating(result[cnt]); // finally, check whether entry is on any desktop, and if so, // use desktop name in that column ob[5] = desktopObj.getDesktopNameOfEntry(result[cnt]); // and add that content as a new row to the table dtm.addRow(ob); } // create a new stringbuilder to prepare the label // that shows the amount of found entries StringBuilder sb = new StringBuilder(""); sb.append("("); sb.append(String.valueOf(dtm.getRowCount())); sb.append(" "); sb.append(resourceMap.getString("hitsText")); sb.append(")"); // set labeltext jLabelHits.setText(sb.toString()); // work done tableUpdateActive = false; // enable filter text field jTextFieldFilterList.setEnabled(true); } } /** * This method updates the display, i.e. it retrieves the selected entry from * the jTableResults and fills the textfields with content (displaying the entry). */ private void updateDisplay() { // get selected row int row = jTableResults.getSelectedRow(); // if we have any selections, go on if (row!=-1) { // retrieve the value... Object o = jTableResults.getValueAt(row, 0); try { // ...and try to convert it to an integer value int selection = Integer.parseInt(o.toString()); // prepare array for search terms which might be highlighted String[] sts = getHighlightSearchterms(); displayZettelContent(selection,sts); // // Here we set up the keywordlist for the JList // // retrieve the keywords of the selected entry String[] kws = dataObj.getKeywords(selection); // prepare the JList which will display the keywords keywordListModel.clear(); // check whether any keywords have been found if (kws!=null) { // sort the array if (kws.length>0) Arrays.sort(kws); // iterate the string array and add its content to the list model for (String kw : kws ) keywordListModel.addElement(kw); } // if we have any search terms, we want to select the related keywords... if (sts!=null) { // create an integer list LinkedList<Integer> l = new LinkedList<>(); // iterate all search terms for (String s : sts) { // try to find the keyword in the jList for (int cnt=0; cnt<keywordListModel.getSize(); cnt++) if (s.equalsIgnoreCase(keywordListModel.get(cnt).toString())) l.add(cnt); } // create int-array int [] selections = new int[l.size()]; // copy all elements of the list to the array for (int cnt=0; cnt<l.size(); cnt++) selections[cnt] = l.get(cnt); // set selected indices for the jList jListKeywords.setSelectedIndices(selections); } // if we don't have highlighting, clear selection else jListKeywords.clearSelection(); // if we want to update the entry immediately, show entry in mainframe as well if (settingsObj.getShowSearchEntry()) mainframe.showEntry(selection); // finally, set desktop selected // setDesktopEntrySelected(desktopObj.isEntryInAnyDesktop(selection)); } catch (NumberFormatException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } } else { jEditorPaneSearchEntry.setText(""); keywordListModel.clear(); } } public void updateDisplayAfterEditing() { // get selected row int row = jTableResults.getSelectedRow(); // if we have any selections, go on if (row!=-1) { // retrieve the value... Object o = jTableResults.getValueAt(row, 0); try { // ...and try to convert it to an integer value int selection = Integer.parseInt(o.toString()); // prepare array for search terms which might be highlighted String[] sts = getHighlightSearchterms(); displayZettelContent(selection,sts); } catch (NumberFormatException e) { Constants.zknlogger.log(Level.WARNING,e.getLocalizedMessage()); } } } private String[] getHighlightSearchterms() { // prepare array for search terms which might be highlighted String[] sts = null; // get search terms, if highlighting is requested if (settingsObj.getHighlightSearchResults()) { // get the selected index, i.e. the searchrequest we want to retrieve int index = jComboBoxSearches.getSelectedIndex(); // get the related search terms sts = searchrequest.getSearchTerms(index); // check whether the search was a synonym-search. if yes, add synonyms to search terms if (searchrequest.isSynonymSearch(index)) { // create new linked list that will contain all highlight-terms, including // the related synonyms of the highlight-terms LinkedList<String> highlight = new LinkedList<>(); // go through all searchterms for (String s : sts) { // get the synonym-line for each search term String[] synline = synonymsObj.getSynonymLineFromAny(s,false); // if we have synonyms... if (synline!=null) { // add them to the linked list, if they are new for (String sy : synline) { if (!highlight.contains(sy)) highlight.add(sy); } } // else simply add the search term to the linked list else if (!highlight.contains(s)) { highlight.add(s); } } if (highlight.size()>0) sts = highlight.toArray(new String[highlight.size()]); } } return sts; } private void displayZettelContent(int nr, String[] highlightterms) { // set highlight search terms HtmlUbbUtil.setHighlighTerms(highlightterms, HtmlUbbUtil.HIGHLIGHT_STYLE_SEARCHRESULTS, settingsObj.getHighlightWholeWordSearch()); // retrieve the string array of the first entry String disp = dataObj.getEntryAsHtml(nr, (settingsObj.getHighlightSegments())?getSelectedKeywordsFromList():null, Constants.FRAME_SEARCH); // in case parsing was ok, display the entry if (Tools.isValidHTML(disp,nr)) { // set entry information in the main textfield jEditorPaneSearchEntry.setText(disp); } // else show error message box to user and tell him what to do else { StringBuilder cleanedContent = new StringBuilder(""); cleanedContent.append("<body><div style=\"margin:5px;padding:5px;background-color:#dddddd;color:#800000;\">"); URL imgURL = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getClass().getResource("/de/danielluedecke/zettelkasten/resources/icons/error.png"); cleanedContent.append("<img border=\"0\" src=\"").append(imgURL).append("\"> "); cleanedContent.append(resourceMap.getString("incorrectNestedTagsText")); cleanedContent.append("</div>").append(dataObj.getCleanZettelContent(nr)).append("</body>"); // and display clean content instead jEditorPaneSearchEntry.setText(cleanedContent.toString()); } // place caret, so content scrolls to top jEditorPaneSearchEntry.setCaretPosition(1); } @Action public void exportEntries() { // retrieve the selected index from the combobox, so we know the search result. // then get the related searchresults (entries as integer array) from the search-reuest // finally, call the mainframe's exportwindow-method and pass the int-array with the entry-numbers mainframe.exportEntries(searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex())); } @Action public void editEntry() { // get selected entry int row = jTableResults.getSelectedRow(); // when we have a valid selection, go on if (row!=-1) { // remember that entry editing came from search window mainframe.editEntryFromSearchWindow = true; // open edit window mainframe.openEditWindow(true,Integer.parseInt(jTableResults.getValueAt(row, 0).toString()),false,false,-1); } } @Action public void duplicateEntry() { // get selected entry int row = jTableResults.getSelectedRow(); // when we have a valid selection, go on if (row!=-1) mainframe.duplicateEntry(Integer.parseInt(jTableResults.getValueAt(row, 0).toString())); } @Action public void duplicateSearch() { searchrequest.duplicateSearchRequest(); updateComboBox(0,-1); } @Action public void findAndReplace() { // find and replace within search-results-entries, and update display if we have any replacements. if (mainframe.replace(searchframe,null, getSelectedEntriesFromTable())) updateDisplay(); } /** * This method gets all selected elements of the jListEntryKeywords * and returns them in an array. * * @return a string-array containing all selected keywords, or null if no selection made */ private String[] getSelectedKeywordsFromList() { // get selected values List<String> values = jListKeywords.getSelectedValuesList(); // if we have any selections, go on if (!values.isEmpty()) { // create string array for selected values // return complete array return values.toArray(new String[values.size()]); } // ...or null, if error occured. return null; } @Action(enabledProperty = "textSelected") public void newSearchFromSelection() { // open the search dialog // the parameters are as following: mainframe.startSearch(new String[] {jEditorPaneSearchEntry.getSelectedText()}, // string-array with search terms Constants.SEARCH_AUTHOR, // the type of search, i.e. where to look Constants.LOG_OR, // the logical combination false, // whole-word-search false, // match-case-search settingsObj.getSearchAlwaysSynonyms(), // whether synonyms should be included or not false, // time-period search false, // whether the search terms contain regular expressions or not "", // timestamp, date from (period start) "", // timestamp, date to (period end) 0, // timestampindex (whether the period should focus on creation or edited date, or both) false, // no display - whether the results should only be used for adding entries to the desktop or so (true), or if a searchresults-window shoud be opened (false) Constants.STARTSEARCH_USUAL, // whether we have a usual search, or a search for entries without remarks or keywords and so on - see related method findEntryWithout Constants.SEARCH_USUAL); } @Action(enabledProperty = "listSelected") public void newSearchFromKeywordsLogOr() { // open the search dialog // the parameters are as following: mainframe.startSearch(getSelectedKeywordsFromList(), // string-array with search terms Constants.SEARCH_KEYWORDS, // the type of search, i.e. where to look Constants.LOG_OR, // the logical combination true, // whole-word-search true, // match-case-search settingsObj.getSearchAlwaysSynonyms(), // whether synonyms should be included or not false, // time-period search false, // whether the search terms contain regular expressions or not "", // timestamp, date from (period start) "", // timestamp, date to (period end) 0, // timestampindex (whether the period should focus on creation or edited date, or both) false, // no display - whether the results should only be used for adding entries to the desktop or so (true), or if a searchresults-window shoud be opened (false) Constants.STARTSEARCH_USUAL, // whether we have a usual search, or a search for entries without remarks or keywords and so on - see related method findEntryWithout Constants.SEARCH_USUAL); } @Action(enabledProperty = "listSelected") public void newSearchFromKeywordsLogAnd() { // open the search dialog // the parameters are as following: mainframe.startSearch(getSelectedKeywordsFromList(), // string-array with search terms Constants.SEARCH_KEYWORDS, // the type of search, i.e. where to look Constants.LOG_AND, // the logical combination true, // whole-word-search true, // match-case-search settingsObj.getSearchAlwaysSynonyms(), // whether synonyms should be included or not false, // time-period search false, // whether the search terms contain regular expressions or not "", // timestamp, date from (period start) "", // timestamp, date to (period end) 0, // timestampindex (whether the period should focus on creation or edited date, or both) false, // no display - whether the results should only be used for adding entries to the desktop or so (true), or if a searchresults-window shoud be opened (false) Constants.STARTSEARCH_USUAL, // whether we have a usual search, or a search for entries without remarks or keywords and so on - see related method findEntryWithout Constants.SEARCH_USUAL); } @Action(enabledProperty = "listSelected") public void newSearchFromKeywordsLogNot() { // open the search dialog // the parameters are as following: mainframe.startSearch(getSelectedKeywordsFromList(), // string-array with search terms Constants.SEARCH_KEYWORDS, // the type of search, i.e. where to look Constants.LOG_NOT, // the logical combination true, // whole-word-search true, // match-case-search settingsObj.getSearchAlwaysSynonyms(), // whether synonyms should be included or not false, // time-period search false, // whether the search terms contain regular expressions or not "", // timestamp, date from (period start) "", // timestamp, date to (period end) 0, // timestampindex (whether the period should focus on creation or edited date, or both) false, // no display - whether the results should only be used for adding entries to the desktop or so (true), or if a searchresults-window shoud be opened (false) Constants.STARTSEARCH_USUAL, // whether we have a usual search, or a search for entries without remarks or keywords and so on - see related method findEntryWithout Constants.SEARCH_USUAL); } /** * This method opens the usual find-dialog and lets the user enter a "new" search request. the current * search results are then filtered according to the search-parameters entered by the user. a new * searchresult is being displayed after that. * <br><br> * So the user can create a new search result with those previous entries removed that do not match * the search criteria. */ @Action public void filterSearch() { // if dialog window isn't already created, do this now if (null == searchDlg) { // create a new dialog window searchDlg = new CSearchDlg(this,searchrequest,settingsObj,null); // center window searchDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(searchDlg); // open the search dialog // the parameters are as following: // - string-array with search results // - the type of search, i.e. where to look // - logical-and-combination // - whole words // - case-sensitive search if (!searchDlg.isCancelled()) { startSearch(Constants.SEARCH_USUAL, searchDlg.getSearchTerms(), searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()), searchDlg.getWhereToSearch(), searchDlg.getLogical(), searchDlg.isWholeWord(), searchDlg.isMatchCase(), searchDlg.isSynonymsIncluded(), searchDlg.isRegExSearch(), searchDlg.isTimestampSearch(), searchDlg.getDateFromValue(), searchDlg.getDateToValue(), searchDlg.getTimestampIndex()); } searchDlg.dispose(); searchDlg = null; } /** * This method opens a dialog with a list that contains all keywords of the current search result's entries. * The user can than choose keywords from this list and filter the search results, i.e. creating a new * search result with those previous entries removed that do not match the search criteria (i.e.: don't * have the selected keywords). */ @Action public void filterKeywords() { // retrieve current entries from the list int[] entries = searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()); // create linked list as parameter for filter-dialog LinkedList<String> keywords = new LinkedList<>(); // go through all entries for (int e : entries) { // get keywords of each entries String[] kws = dataObj.getKeywords(e); // now go through all keywords of that entry // if keyword does not exist, add it to list if (kws!=null) for (String k : kws) if (!keywords.contains(k)) keywords.add(k); } // if dialog window isn't already created, do this now if (null == filterSearchDlg) { // create a new dialog window filterSearchDlg = new CFilterSearch(this,settingsObj,keywords,null,true); // center window filterSearchDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(filterSearchDlg); // open the search dialog // the parameters are as following: // - string-array with search results // - the type of search, i.e. where to look // - logical-and-combination // - whole words // - case-sensitive search if (filterSearchDlg.getFilterTerms()!=null) { startSearch(Constants.SEARCH_USUAL, filterSearchDlg.getFilterTerms(), searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()), Constants.SEARCH_KEYWORDS, filterSearchDlg.getLogical(), true, true, settingsObj.getSearchAlwaysSynonyms(), false,false,"","",0); } filterSearchDlg.dispose(); filterSearchDlg = null; } @Action public void filterTopLevelLuhmann() { // open the search dialog // the parameters are as following: // - string-array with search results // - the type of search, i.e. where to look // - logical-and-combination // - whole words // - case-sensitive search startSearch(Constants.SEARCH_TOP_LEVEL_LUHMANN, null, searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()), -1, Constants.LOG_OR, false, false, false, false, false, null, null, 0); } /** * This method opens a dialog with a list that contains all authors of the current search result's entries. * The user can than choose authors from this list and filter the search results, i.e. creating a new * search result with those previous entries removed that do not match the search criteria (i.e.: don't * have the selected authors). */ @Action public void filterAuthors() { // retrieve current entries from the list int[] entries = searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()); // create linked list as parameter for filter-dialog LinkedList<String> authors = new LinkedList<>(); // go through all entries for (int e : entries) { // get authors of each entries String[] aus = dataObj.getAuthors(e); // now go through all keywords of that entry // if keyword does not exist, add it to list if (aus!=null) for (String a : aus) if (!authors.contains(a)) authors.add(a); } // if dialog window isn't already created, do this now if (null == filterSearchDlg) { // create a new dialog window filterSearchDlg = new CFilterSearch(this,settingsObj,authors,null,true); // center window filterSearchDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(filterSearchDlg); // open the search dialog // the parameters are as following: // - string-array with search results // - the type of search, i.e. where to look // - logical-and-combination // - whole words // - case-sensitive search if (filterSearchDlg.getFilterTerms()!=null) { startSearch(Constants.SEARCH_USUAL, filterSearchDlg.getFilterTerms(), searchrequest.getSearchResults(jComboBoxSearches.getSelectedIndex()), Constants.SEARCH_AUTHOR, filterSearchDlg.getLogical(), true,true, settingsObj.getSearchAlwaysSynonyms(), false,false,"","",0); } filterSearchDlg.dispose(); filterSearchDlg = null; } /** * Opens the search dialog. * <br><br> * In case of keyword- and author-search <i>from the table</i> (lists), we can neglect the last * parameter, since keyword- and author-search simply functions by searching * for the index-numbers, that are always - or never - case sensitive relevant. * <br><br> * When we have searchterms from the search-dialog, the user also can search for <i>parts</i> inside * a keyword-string, so here the whole-word-parameter is relevant, since we then don't compare by index- * numbers, but by the string-value of the keywords/authors. * * @param searchterms string-array with search terms * @param searchin the entries where the search should be apllied to, i.e. when we want to filter a certain search result * @param where the type of search, i.e. where to look, e.g. searching for keywords, authors, text etc. * @param logand logical-and-combination * @param wholeword whether we look for whole words or also parts of a word/phrase * @param matchcase whether the search should be case sensitive or not * @param synonyms whether the search should include synonyms or not * @param timesearch whether the user requested a time-search, i.e. a search for entries that were created * or changed within a certain period * @param datefrom the start of the period, when a timesearch is requested. format: "yymmdd". * @param dateto the end of the period, when a timesearch is requested. format: "yymmdd". * @param timestampindex */ private void startSearch(int searchtype, String[] searchterms, int[] searchin, int where, int logical, boolean wholeword, boolean matchcase, boolean syno, boolean regex, boolean timesearch, String datefrom, String dateto, int timestampindex) { // check whether we have valid searchterms or not... if ((null==searchterms || searchterms.length<1) && searchtype!=Constants.SEARCH_TOP_LEVEL_LUHMANN) return; // if dialog window isn't already created, do this now if (null == taskDlg) { // get parent und init window taskDlg = new TaskProgressDialog(this, TaskProgressDialog.TASK_SEARCH, dataObj, searchrequest, synonymsObj, searchtype, searchterms, searchin, where, logical, wholeword, matchcase, syno, regex, timesearch, datefrom, dateto, timestampindex, false, settingsObj.getSearchRemovesFormatTags()); // center window taskDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(taskDlg); // we have to manually dispose the window and release the memory // because next time this method is called, the showKwlDlg is still not null, // i.e. the constructor is not called (because the if-statement above is not true) // dispose the window and clear the object taskDlg.dispose(); taskDlg = null; // check whether we have any search results at all if (searchrequest.getCurrentSearchResults()!=null) { showLatestSearchResult(); } else { // display error message box that nothing was found JOptionPane.showMessageDialog(this,resourceMap.getString("errNothingFoundMsg"),resourceMap.getString("errNothingFoundTitle"),JOptionPane.PLAIN_MESSAGE); } } @Action public void showLongDesc() { // display long description JOptionPane.showMessageDialog(null,searchrequest.getLongDescription(jComboBoxSearches.getSelectedIndex()),resourceMap.getString("longDescTitle"),JOptionPane.PLAIN_MESSAGE); } @Action public void showHighlightSettings() { if (null == highlightSettingsDlg) { highlightSettingsDlg = new CHighlightSearchSettings(this,settingsObj,HtmlUbbUtil.HIGHLIGHT_STYLE_SEARCHRESULTS); highlightSettingsDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(highlightSettingsDlg); highlightSettingsDlg.dispose(); highlightSettingsDlg=null; updateDisplay(); } /** * This method retrieves the selected entries and adds them to the deskop, by calling * the mainframe's method addToDesktop(). */ @Action public void addToDesktop() { // get selected entries int[] entries=getSelectedEntriesFromTable(); // if we have any valid values, add them to desktop if ((entries!=null)&&(entries.length>0)) mainframe.addToDesktop(entries); } /** * This method retrieves the selected entries and adds them to the deskop, by calling * the mainframe's method addToDesktop(). */ @Action public void addToBookmarks() { // get selected entries int[] entries=getSelectedEntriesFromTable(); // if we have any valid values... if ((entries!=null)&&(entries.length>0)) { // add them as bookmarks mainframe.addToBookmarks(entries, false); // and display related tab mainframe.menuShowBookmarks(); } } /** * This method retrieves the selected entries and adds them as follower-numbers to that * entry that is selected in the mainframe's luhmann-tab, in the jTreeLuhmann. */ @Action public void addToLuhmann() { // get selected entries int[] entries=getSelectedEntriesFromTable(); // if we have any valid values... if ((entries!=null)&&(entries.length>0)) { // add them as followers mainframe.addToLuhmann(entries); // and display related tab mainframe.menuShowLuhmann(); } } /** * This method retrieves the selected entries and adds them as manual link to the * mainframe's current entry. */ @Action public void addToManLinks() { // get selected entries int[] entries=getSelectedEntriesFromTable(); // if we have any valid values... if ((entries!=null)&&(entries.length>0)) { // add them as followers mainframe.addToManLinks(entries); // and display related tab mainframe.menuShowLinks(); } } /** * Selects all entries in the table with the search results */ @Action public void selectAll() { jTableResults.selectAll(); } /** * This method gets all selected elements of the jTableResults * and returns them in an array. * * @return a integer-array containing all selected entries, or null if no selection made */ private int[] getSelectedEntriesFromTable() { // get selected rows int[] rows = jTableResults.getSelectedRows(); // if we have any selections, go on if (rows!=null && rows.length>0) { // create string array for selected values int[] entries = new int[rows.length]; try { // iterate array for (int cnt=0; cnt<rows.length; cnt++) { // copy value from table to array entries[cnt] = Integer.parseInt(jTableResults.getValueAt(rows[cnt], 0).toString()); } // return complete array return entries; } catch (NumberFormatException e) { return null; } } // ...or null, if error occured. return null; } /** * This method removes the selected result-entry-numbers from the results list. */ @Action public void removeEntry() { // get selected rows int[] rows = jTableResults.getSelectedRows(); // if we have any selections, go on if ((rows!=null)&&(rows.length>0)) { // get the selected searchrequest int i = jComboBoxSearches.getSelectedIndex(); for (int cnt=rows.length-1; cnt>=0; cnt--) { // retrieve the values... Object o = jTableResults.getValueAt(rows[cnt], 0); // ...and try to convert it to an integer value int selection = Integer.parseInt(o.toString()); // delete the entry from the search request searchrequest.deleteResultEntry(i, selection); } updateComboBox(rows[0],-1); } } /** * This method deletes the selected entries completely from the dataset */ @Action public void deleteEntryComplete() { // first display the to be deleted entry in the main-frame, so the user is not confused // about which entry to delete... displayEntryInMainframe(); // try to delete the entry // and bring search results frame to front... if (mainframe.deleteEntries(getSelectedEntriesFromTable())) this.toFront(); } /** * This method removes all(!) search requests, i.e. clears the search-request-xml-data. */ @Action public void removeAllSearchResults() { // and create a JOptionPane with yes/no/cancel options int msgOption = JOptionPane.showConfirmDialog(null, resourceMap.getString("askForDeleteAllMsg"), resourceMap.getString("askForDeleteAllTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE); // if the user wants to proceed, copy the image now if (JOptionPane.YES_OPTION == msgOption) { // completeley remove all search requests searchrequest.deleteAllSearchRequests(); // reset combobox updateComboBox(-1,-1); } } private void displayEntryInMainframe() { // get selected entry int row = jTableResults.getSelectedRow(); // when we have a valid selection, go on if (row!=-1) mainframe.showEntry(Integer.parseInt(jTableResults.getValueAt(row, 0).toString())); } /** * This method removes a complete search request from the search results. */ @Action public void removeSearchResult() { // and create a JOptionPane with yes/no/cancel options int msgOption = JOptionPane.showConfirmDialog(null, resourceMap.getString("askForDeleteSearchMsg"), resourceMap.getString("askForDeleteSearchTitle"), JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE); // if the user wants to proceed, copy the image now if (JOptionPane.YES_OPTION == msgOption) { // get the selected searchrequest int i = jComboBoxSearches.getSelectedIndex(); // delete complete search request searchrequest.deleteSearchRequest(i); // update combo box updateComboBox(0,-1); } } /** * Closes the window. */ @Action public void closeWindow() { // check whether memory usage is logged. if so, tell logger that new entry windows was opened if (settingsObj.isMemoryUsageLogged) { // log info Constants.zknlogger.log(Level.INFO,"Memory usage logged. Search Results Window closed."); } dispose(); setVisible(false); // try to motivate garbage collector System.gc(); } /** * Activates or deactivates the fullscreen-mode, thus switching between fullscreen and normal view. */ @Action(enabledProperty = "fullScreenSupp") public void viewFullScreen() { // check whether fullscreen is possible or not... if (graphicdevice.isFullScreenSupported()) { // if we already have a fullscreen window, quit fullscreen if (graphicdevice.getFullScreenWindow()!=null) quitFullScreen(); // else show fullscreen window else showFullScreen(); } } /** * This method activates the fullscreen-mode, if it's not already activated yet. To have a * fullscreen-window without decoration, the frame is disposed first, then the decoration * will be removed and the window made visible again. */ private void showFullScreen() { // check whether fullscreen is supported, and if we currently have a fullscreen-window if (graphicdevice.isFullScreenSupported() && null==graphicdevice.getFullScreenWindow()) { // dispose frame, so we can remove the decoration when setting full screen mode searchframe.dispose(); // hide menubar searchMenuBar.setVisible(false); // set frame non-resizable searchframe.setResizable(false); try { // remove decoration searchframe.setUndecorated(true); } catch (IllegalComponentStateException e) { Constants.zknlogger.log(Level.SEVERE,e.getLocalizedMessage()); } // show frame again searchframe.setVisible(true); // set fullscreen mode to this window graphicdevice.setFullScreenWindow(this); } } /** * This method <i>de</i>activates the fullscreen-mode, if it's not already deactivated yet. */ private void quitFullScreen() { // check whether fullscreen is supported, and if we currently have a fullscreen-window if (graphicdevice.isFullScreenSupported() && graphicdevice.getFullScreenWindow()!=null) { // disable fullscreen-mode graphicdevice.setFullScreenWindow(null); // hide menubar searchMenuBar.setVisible(true); // make frame resizable again searchframe.setResizable(true); // dispose frame, so we can restore the decoration searchframe.dispose(); try { // set decoration searchframe.setUndecorated(false); } catch (IllegalComponentStateException e) { Constants.zknlogger.log(Level.SEVERE,e.getLocalizedMessage()); } // show frame again searchframe.setVisible(true); } } /** * This method is used to pass paramaters to this dialog, so it can display results * when it is made visible. Since we don't dispose and clear this dialog, we cannot * call the constructor each time, so we need another method where we can pass parameters * of new search results. * <br><br> * This dialog is not disposed and cleared, because we want to keep former search results, even * when the user "closes" (i.e.: hides) this dialog. */ public void showLatestSearchResult() { // here we update the combo box, not the display. since selecting // an item, which is done in this method, fires an action to the action listener, // the display update should be achieved through the combobox's actionlistener. updateComboBox(-1,searchrequest.getCount()-1); // and make dialog visible setVisible(true); // repaint the components (necessary, since the components are not properly repainted else) repaint(); // set input focus this.setAlwaysOnTop(true); this.toFront(); this.requestFocusInWindow(); this.setAlwaysOnTop(false); setAlwaysOnTop(true); setAlwaysOnTop(false); toFront(); } private void openAttachment(javax.swing.event.HyperlinkEvent evt) { // retrieve the event type, e.g. if a link was clicked by the user HyperlinkEvent.EventType typ = evt.getEventType(); // get the description, to check whether we have a file or a hyperlink to a website String linktype = evt.getDescription(); // if the link was clicked, proceed if (typ==HyperlinkEvent.EventType.ACTIVATED) { // call method that handles the hyperlink-click String returnValue = Tools.openHyperlink(linktype, this, Constants.FRAME_SEARCH, dataObj, bibtexObj, settingsObj, jEditorPaneSearchEntry, Integer.parseInt(jTableResults.getValueAt(jTableResults.getSelectedRow(), 0).toString())); // check whether we have a return value. this might be the case either when the user clicked on // a footenote, or on the rating-stars if (returnValue!=null) { // here we have a reference to another entry if (returnValue.startsWith("#z_") || returnValue.startsWith("#cr_")) { // show entry mainframe.showEntry(dataObj.getCurrentZettelPos()); } // edit cross references else if (returnValue.equalsIgnoreCase("#crt")) { mainframe.editManualLinks(); } // check whether a rating was requested else if (returnValue.startsWith("#rateentry")) { try { // retrieve entry-number int entrynr = Integer.parseInt(linktype.substring(10)); // open rating-dialog if (null == rateEntryDlg) { rateEntryDlg = new CRateEntry(this,dataObj,entrynr); rateEntryDlg.setLocationRelativeTo(this); } ZettelkastenApp.getApplication().show(rateEntryDlg); // check whether dialog was cancelled or not if (!rateEntryDlg.isCancelled()) { // update display displayZettelContent(entrynr, null); } rateEntryDlg.dispose(); rateEntryDlg=null; // try to motivate garbage collector System.gc(); } catch (NumberFormatException ex) { // log error Constants.zknlogger.log(Level.WARNING,ex.getLocalizedMessage()); Constants.zknlogger.log(Level.WARNING, "Could not rate entry. Link-text was {0}", linktype); } } } } } /** * This class sets up a selection listener for the tables. each table which shall react * on selections, e.g. by showing an entry, gets this selectionlistener in the method * {@link #initSelectionListeners() initSelectionListeners()}. */ public class SelectionListener implements ListSelectionListener { JTable table; // It is necessary to keep the table since it is not possible // to determine the table from the event's source SelectionListener(JTable table) { this.table = table; } @Override public void valueChanged(ListSelectionEvent e) { // if we have an update, don't react on selection changes if (tableUpdateActive) return; // get list selection model ListSelectionModel lsm = (ListSelectionModel)e.getSource(); // set value-adjusting to true, so we don't fire multiple value-changed events... lsm.setValueIsAdjusting(true); if (jTableResults==table) updateDisplay(); } } /** * This variable indicates whether we have selected text or not - and en/disables * the new-search-functions. see {@link #newSearchFromAuthor() newSearchFromAuthor()} * and {@link #newSearchFromSelection() newSearchFromSelection()}. */ private boolean textSelected = false; public boolean isTextSelected() { return textSelected; } public void setTextSelected(boolean b) { boolean old = isTextSelected(); this.textSelected = b; firePropertyChange("textSelected", old, isTextSelected()); } /** * This variable indicates whether we have selected an item in the jListKeywords or not - and en/disables * the new-search-functions. see {@link #newSearchFromKeywordsLogOr() newSearchFromKeywordsLogOr()} */ private boolean listSelected = false; public boolean isListSelected() { return listSelected; } public void setListSelected(boolean b) { boolean old = isListSelected(); this.listSelected = b; firePropertyChange("listSelected", old, isListSelected()); } /** * This variable indicates whether we have selected an entry from the * search results list (jTableResults) that is also present on any * desktop. */ private boolean desktopEntrySelected = false; public boolean isDesktopEntrySelected() { return desktopEntrySelected; } public void setDesktopEntrySelected(boolean b) { boolean old = isDesktopEntrySelected(); this.desktopEntrySelected = b; firePropertyChange("desktopEntrySelected", old, isDesktopEntrySelected()); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { searchToolbar = new javax.swing.JToolBar(); tb_copy = new javax.swing.JButton(); tb_selectall = new javax.swing.JButton(); jSeparator12 = new javax.swing.JToolBar.Separator(); tb_editentry = new javax.swing.JButton(); tb_remove = new javax.swing.JButton(); jSeparator3 = new javax.swing.JToolBar.Separator(); tb_manlinks = new javax.swing.JButton(); tb_luhmann = new javax.swing.JButton(); tb_bookmark = new javax.swing.JButton(); tb_desktop = new javax.swing.JButton(); jSeparator5 = new javax.swing.JToolBar.Separator(); tb_highlight = new javax.swing.JButton(); searchMainPanel = new javax.swing.JPanel(); jSplitPaneSearch1 = new javax.swing.JSplitPane(); jPanel1 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); jTableResults = (settingsObj.isMacStyle()) ? com.explodingpixels.macwidgets.MacWidgetFactory.createITunesTable(null) : new javax.swing.JTable(); jTextFieldFilterList = new javax.swing.JTextField(); jButtonResetList = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jSplitPaneSearch2 = new javax.swing.JSplitPane(); jPanel3 = new javax.swing.JPanel(); jScrollPane2 = new javax.swing.JScrollPane(); jEditorPaneSearchEntry = new javax.swing.JEditorPane(); jPanel4 = new javax.swing.JPanel(); jScrollPane4 = new javax.swing.JScrollPane(); jListKeywords = MacSourceList.createMacSourceList(); searchStatusPanel = new javax.swing.JPanel(); jPanel9 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); jComboBoxSearches = new javax.swing.JComboBox(); jLabelHits = new javax.swing.JLabel(); jButtonDeleteSearch = new javax.swing.JButton(); searchMenuBar = new javax.swing.JMenuBar(); searchFileMenu = new javax.swing.JMenu(); fileMenuLongDesc = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JSeparator(); fileMenuDuplicateSearch = new javax.swing.JMenuItem(); jSeparator22 = new javax.swing.JSeparator(); fileMenuDeleteSearch = new javax.swing.JMenuItem(); fileMenuDeleteAll = new javax.swing.JMenuItem(); jSeparator20 = new javax.swing.JSeparator(); fileMenuExport = new javax.swing.JMenuItem(); jSeparator13 = new javax.swing.JSeparator(); fileMenuClose = new javax.swing.JMenuItem(); searchEditMenu = new javax.swing.JMenu(); editMenuCopy = new javax.swing.JMenuItem(); editMenuSelectAll = new javax.swing.JMenuItem(); jSeparator10 = new javax.swing.JSeparator(); editMenuDelete = new javax.swing.JMenuItem(); jSeparator16 = new javax.swing.JSeparator(); editMenuEditEntry = new javax.swing.JMenuItem(); editMenuDuplicateEntry = new javax.swing.JMenuItem(); editMenuFindReplace = new javax.swing.JMenuItem(); jSeparator4 = new javax.swing.JSeparator(); editMenuDeleteEntry = new javax.swing.JMenuItem(); jSeparator21 = new javax.swing.JSeparator(); editMenuAddKeywordsToSelection = new javax.swing.JMenuItem(); editMenuAddAuthorsToSelection = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); editMenuManLinks = new javax.swing.JMenuItem(); editMenuLuhmann = new javax.swing.JMenuItem(); editMenuBookmarks = new javax.swing.JMenuItem(); jSeparator6 = new javax.swing.JSeparator(); editMenuDesktop = new javax.swing.JMenuItem(); searchFilterMenu = new javax.swing.JMenu(); filterSearch = new javax.swing.JMenuItem(); jSeparator14 = new javax.swing.JSeparator(); filterKeywords = new javax.swing.JMenuItem(); jSeparator15 = new javax.swing.JSeparator(); filterAuthors = new javax.swing.JMenuItem(); jSeparator23 = new javax.swing.JPopupMenu.Separator(); filterTopLevelLuhmann = new javax.swing.JMenuItem(); searchSearchMenu = new javax.swing.JMenu(); searchMenuSelectionContent = new javax.swing.JMenuItem(); jSeparator19 = new javax.swing.JSeparator(); searchMenuKeywordLogOr = new javax.swing.JMenuItem(); searchMenuKeywordLogAnd = new javax.swing.JMenuItem(); searchMenuKeywordLogNot = new javax.swing.JMenuItem(); searchViewMenu = new javax.swing.JMenu(); viewMenuShowOnDesktop = new javax.swing.JMenuItem(); jSeparator11 = new javax.swing.JSeparator(); viewMenuHighlight = new javax.swing.JCheckBoxMenuItem(); viewMenuHighlightSettings = new javax.swing.JMenuItem(); jSeparator9 = new javax.swing.JSeparator(); viewMenuShowEntry = new javax.swing.JCheckBoxMenuItem(); jSeparator7 = new javax.swing.JPopupMenu.Separator(); jMenuItemSwitchLayout = new javax.swing.JMenuItem(); jSeparator8 = new javax.swing.JPopupMenu.Separator(); viewMenuFullScreen = new javax.swing.JMenuItem(); org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getResourceMap(SearchResultsFrame.class); setTitle(resourceMap.getString("FormSearchResults.title")); // NOI18N setName("FormSearchResults"); // NOI18N searchToolbar.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, resourceMap.getColor("searchToolbar.border.matteColor"))); // NOI18N searchToolbar.setFloatable(false); searchToolbar.setRollover(true); searchToolbar.setName("searchToolbar"); // NOI18N tb_copy.setAction(org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getActionMap(SearchResultsFrame.class, this).get("copy")); tb_copy.setText(resourceMap.getString("tb_copy.text")); // NOI18N tb_copy.setBorderPainted(false); tb_copy.setFocusPainted(false); tb_copy.setFocusable(false); tb_copy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_copy.setName("tb_copy"); // NOI18N tb_copy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_copy); javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(de.danielluedecke.zettelkasten.ZettelkastenApp.class).getContext().getActionMap(SearchResultsFrame.class, this); tb_selectall.setAction(actionMap.get("selectAll")); // NOI18N tb_selectall.setText(resourceMap.getString("tb_selectall.text")); // NOI18N tb_selectall.setBorderPainted(false); tb_selectall.setFocusPainted(false); tb_selectall.setFocusable(false); tb_selectall.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_selectall.setName("tb_selectall"); // NOI18N tb_selectall.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_selectall); jSeparator12.setName("jSeparator12"); // NOI18N searchToolbar.add(jSeparator12); tb_editentry.setAction(actionMap.get("editEntry")); // NOI18N tb_editentry.setText(resourceMap.getString("tb_editentry.text")); // NOI18N tb_editentry.setBorderPainted(false); tb_editentry.setFocusPainted(false); tb_editentry.setFocusable(false); tb_editentry.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_editentry.setName("tb_editentry"); // NOI18N tb_editentry.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_editentry); tb_remove.setAction(actionMap.get("removeEntry")); // NOI18N tb_remove.setText(resourceMap.getString("tb_remove.text")); // NOI18N tb_remove.setBorderPainted(false); tb_remove.setFocusPainted(false); tb_remove.setFocusable(false); tb_remove.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_remove.setName("tb_remove"); // NOI18N tb_remove.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_remove); jSeparator3.setName("jSeparator3"); // NOI18N searchToolbar.add(jSeparator3); tb_manlinks.setAction(actionMap.get("addToManLinks")); // NOI18N tb_manlinks.setText(resourceMap.getString("tb_manlinks.text")); // NOI18N tb_manlinks.setBorderPainted(false); tb_manlinks.setFocusPainted(false); tb_manlinks.setFocusable(false); tb_manlinks.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_manlinks.setName("tb_manlinks"); // NOI18N tb_manlinks.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_manlinks); tb_luhmann.setAction(actionMap.get("addToLuhmann")); // NOI18N tb_luhmann.setText(resourceMap.getString("tb_luhmann.text")); // NOI18N tb_luhmann.setBorderPainted(false); tb_luhmann.setFocusPainted(false); tb_luhmann.setFocusable(false); tb_luhmann.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_luhmann.setName("tb_luhmann"); // NOI18N tb_luhmann.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_luhmann); tb_bookmark.setAction(actionMap.get("addToBookmarks")); // NOI18N tb_bookmark.setText(resourceMap.getString("tb_bookmark.text")); // NOI18N tb_bookmark.setBorderPainted(false); tb_bookmark.setFocusPainted(false); tb_bookmark.setFocusable(false); tb_bookmark.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_bookmark.setName("tb_bookmark"); // NOI18N tb_bookmark.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_bookmark); tb_desktop.setAction(actionMap.get("addToDesktop")); // NOI18N tb_desktop.setText(resourceMap.getString("tb_desktop.text")); // NOI18N tb_desktop.setBorderPainted(false); tb_desktop.setFocusPainted(false); tb_desktop.setFocusable(false); tb_desktop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_desktop.setName("tb_desktop"); // NOI18N tb_desktop.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_desktop); jSeparator5.setName("jSeparator5"); // NOI18N searchToolbar.add(jSeparator5); tb_highlight.setAction(actionMap.get("toggleHighlightResults")); // NOI18N tb_highlight.setText(resourceMap.getString("tb_highlight.text")); // NOI18N tb_highlight.setBorderPainted(false); tb_highlight.setFocusPainted(false); tb_highlight.setFocusable(false); tb_highlight.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); tb_highlight.setName("tb_highlight"); // NOI18N tb_highlight.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); searchToolbar.add(tb_highlight); searchMainPanel.setName("searchMainPanel"); // NOI18N searchMainPanel.setLayout(new java.awt.BorderLayout()); jSplitPaneSearch1.setBorder(null); jSplitPaneSearch1.setDividerLocation(240); jSplitPaneSearch1.setOrientation(settingsObj.getSearchFrameSplitLayout()); jSplitPaneSearch1.setName("jSplitPaneSearch1"); // NOI18N jSplitPaneSearch1.setOneTouchExpandable(true); jPanel1.setName("jPanel1"); // NOI18N jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); jScrollPane1.setName("jScrollPane1"); // NOI18N jTableResults.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { }, new String [] { "Zettel", "Überschrift", "Erstellt", "Geändert", "Bewertung", "Schreibtisch" } ) { Class[] types = new Class [] { java.lang.Integer.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Float.class, java.lang.String.class }; boolean[] canEdit = new boolean [] { false, false, false, false, false, false }; public Class getColumnClass(int columnIndex) { return types [columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit [columnIndex]; } }); jTableResults.setDragEnabled(true); jTableResults.setName("jTableResults"); // NOI18N jTableResults.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); jTableResults.setShowVerticalLines(false); jTableResults.getTableHeader().setReorderingAllowed(false); jScrollPane1.setViewportView(jTableResults); if (jTableResults.getColumnModel().getColumnCount() > 0) { jTableResults.getColumnModel().getColumn(0).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title0")); // NOI18N jTableResults.getColumnModel().getColumn(1).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title1")); // NOI18N jTableResults.getColumnModel().getColumn(2).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title2")); // NOI18N jTableResults.getColumnModel().getColumn(3).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title3")); // NOI18N jTableResults.getColumnModel().getColumn(4).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title4")); // NOI18N jTableResults.getColumnModel().getColumn(5).setHeaderValue(resourceMap.getString("jTableResults.columnModel.title5")); // NOI18N } jTextFieldFilterList.setName("jTextFieldFilterList"); // NOI18N jButtonResetList.setAction(actionMap.get("resetResultslist")); // NOI18N jButtonResetList.setIcon(resourceMap.getIcon("jButtonResetList.icon")); // NOI18N jButtonResetList.setBorderPainted(false); jButtonResetList.setContentAreaFilled(false); jButtonResetList.setFocusable(false); jButtonResetList.setName("jButtonResetList"); // NOI18N javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jTextFieldFilterList) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonResetList, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jTextFieldFilterList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButtonResetList)) .addGap(3, 3, 3)) ); jSplitPaneSearch1.setLeftComponent(jPanel1); jPanel2.setName("jPanel2"); // NOI18N jSplitPaneSearch2.setBorder(null); jSplitPaneSearch2.setDividerLocation(280); jSplitPaneSearch2.setName("jSplitPaneSearch2"); // NOI18N jSplitPaneSearch2.setOneTouchExpandable(true); jPanel3.setName("jPanel3"); // NOI18N jScrollPane2.setBorder(null); jScrollPane2.setName("jScrollPane2"); // NOI18N jEditorPaneSearchEntry.setEditable(false); jEditorPaneSearchEntry.setBorder(null); jEditorPaneSearchEntry.setContentType(resourceMap.getString("jEditorPaneSearchEntry.contentType")); // NOI18N jEditorPaneSearchEntry.setName("jEditorPaneSearchEntry"); // NOI18N jScrollPane2.setViewportView(jEditorPaneSearchEntry); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 280, Short.MAX_VALUE) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE) ); jSplitPaneSearch2.setLeftComponent(jPanel3); jPanel4.setName("jPanel4"); // NOI18N jScrollPane4.setName("jScrollPane4"); // NOI18N jListKeywords.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("jListKeywords.border.title"))); // NOI18N jListKeywords.setModel(keywordListModel); jListKeywords.setName("jListKeywords"); // NOI18N jScrollPane4.setViewportView(jListKeywords); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 119, Short.MAX_VALUE) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE) ); jSplitPaneSearch2.setRightComponent(jPanel4); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSplitPaneSearch2) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSplitPaneSearch2) ); jSplitPaneSearch1.setRightComponent(jPanel2); searchMainPanel.add(jSplitPaneSearch1, java.awt.BorderLayout.CENTER); searchStatusPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 0, 0, 0, resourceMap.getColor("searchStatusPanel.border.matteColor"))); // NOI18N searchStatusPanel.setMinimumSize(new java.awt.Dimension(200, 16)); searchStatusPanel.setName("searchStatusPanel"); // NOI18N jPanel9.setName("jPanel9"); // NOI18N jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N jLabel1.setName("jLabel1"); // NOI18N jComboBoxSearches.setName("jComboBoxSearches"); // NOI18N jLabelHits.setText(resourceMap.getString("jLabelHits.text")); // NOI18N jLabelHits.setName("jLabelHits"); // NOI18N jButtonDeleteSearch.setAction(actionMap.get("removeSearchResult")); // NOI18N jButtonDeleteSearch.setIcon(resourceMap.getIcon("jButtonDeleteSearch.icon")); // NOI18N jButtonDeleteSearch.setText(resourceMap.getString("jButtonDeleteSearch.text")); // NOI18N jButtonDeleteSearch.setBorderPainted(false); jButtonDeleteSearch.setFocusPainted(false); jButtonDeleteSearch.setFocusable(false); jButtonDeleteSearch.setName("jButtonDeleteSearch"); // NOI18N javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9); jPanel9.setLayout(jPanel9Layout); jPanel9Layout.setHorizontalGroup( jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel9Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabelHits) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jComboBoxSearches, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButtonDeleteSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap()) ); jPanel9Layout.setVerticalGroup( jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel9Layout.createSequentialGroup() .addGap(3, 3, 3) .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jButtonDeleteSearch) .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabelHits) .addComponent(jLabel1) .addComponent(jComboBoxSearches, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGap(3, 3, 3)) ); javax.swing.GroupLayout searchStatusPanelLayout = new javax.swing.GroupLayout(searchStatusPanel); searchStatusPanel.setLayout(searchStatusPanelLayout); searchStatusPanelLayout.setHorizontalGroup( searchStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); searchStatusPanelLayout.setVerticalGroup( searchStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) ); searchMenuBar.setName("searchMenuBar"); // NOI18N searchFileMenu.setText(resourceMap.getString("searchFileMenu.text")); // NOI18N searchFileMenu.setName("searchFileMenu"); // NOI18N fileMenuLongDesc.setAction(actionMap.get("showLongDesc")); // NOI18N fileMenuLongDesc.setName("fileMenuLongDesc"); // NOI18N searchFileMenu.add(fileMenuLongDesc); jSeparator2.setName("jSeparator2"); // NOI18N searchFileMenu.add(jSeparator2); fileMenuDuplicateSearch.setAction(actionMap.get("duplicateSearch")); // NOI18N fileMenuDuplicateSearch.setName("fileMenuDuplicateSearch"); // NOI18N searchFileMenu.add(fileMenuDuplicateSearch); jSeparator22.setName("jSeparator22"); // NOI18N searchFileMenu.add(jSeparator22); fileMenuDeleteSearch.setAction(actionMap.get("removeSearchResult")); // NOI18N fileMenuDeleteSearch.setName("fileMenuDeleteSearch"); // NOI18N searchFileMenu.add(fileMenuDeleteSearch); fileMenuDeleteAll.setAction(actionMap.get("removeAllSearchResults")); // NOI18N fileMenuDeleteAll.setName("fileMenuDeleteAll"); // NOI18N searchFileMenu.add(fileMenuDeleteAll); jSeparator20.setName("jSeparator20"); // NOI18N searchFileMenu.add(jSeparator20); fileMenuExport.setAction(actionMap.get("exportEntries")); // NOI18N fileMenuExport.setName("fileMenuExport"); // NOI18N searchFileMenu.add(fileMenuExport); jSeparator13.setName("jSeparator13"); // NOI18N searchFileMenu.add(jSeparator13); fileMenuClose.setAction(actionMap.get("closeWindow")); // NOI18N fileMenuClose.setName("fileMenuClose"); // NOI18N searchFileMenu.add(fileMenuClose); searchMenuBar.add(searchFileMenu); searchEditMenu.setText(resourceMap.getString("searchEditMenu.text")); // NOI18N searchEditMenu.setName("searchEditMenu"); // NOI18N editMenuCopy.setAction(actionMap.get("copy")); editMenuCopy.setName("editMenuCopy"); // NOI18N searchEditMenu.add(editMenuCopy); editMenuSelectAll.setAction(actionMap.get("selectAll")); // NOI18N editMenuSelectAll.setName("editMenuSelectAll"); // NOI18N searchEditMenu.add(editMenuSelectAll); jSeparator10.setName("jSeparator10"); // NOI18N searchEditMenu.add(jSeparator10); editMenuDelete.setAction(actionMap.get("removeEntry")); // NOI18N editMenuDelete.setName("editMenuDelete"); // NOI18N searchEditMenu.add(editMenuDelete); jSeparator16.setName("jSeparator16"); // NOI18N searchEditMenu.add(jSeparator16); editMenuEditEntry.setAction(actionMap.get("editEntry")); // NOI18N editMenuEditEntry.setName("editMenuEditEntry"); // NOI18N searchEditMenu.add(editMenuEditEntry); editMenuDuplicateEntry.setAction(actionMap.get("duplicateEntry")); // NOI18N editMenuDuplicateEntry.setName("editMenuDuplicateEntry"); // NOI18N searchEditMenu.add(editMenuDuplicateEntry); editMenuFindReplace.setAction(actionMap.get("findAndReplace")); // NOI18N editMenuFindReplace.setName("editMenuFindReplace"); // NOI18N searchEditMenu.add(editMenuFindReplace); jSeparator4.setName("jSeparator4"); // NOI18N searchEditMenu.add(jSeparator4); editMenuDeleteEntry.setAction(actionMap.get("deleteEntryComplete")); // NOI18N editMenuDeleteEntry.setName("editMenuDeleteEntry"); // NOI18N searchEditMenu.add(editMenuDeleteEntry); jSeparator21.setName("jSeparator21"); // NOI18N searchEditMenu.add(jSeparator21); editMenuAddKeywordsToSelection.setAction(actionMap.get("addKeywordsToEntries")); // NOI18N editMenuAddKeywordsToSelection.setName("editMenuAddKeywordsToSelection"); // NOI18N searchEditMenu.add(editMenuAddKeywordsToSelection); editMenuAddAuthorsToSelection.setAction(actionMap.get("addAuthorsToEntries")); // NOI18N editMenuAddAuthorsToSelection.setName("editMenuAddAuthorsToSelection"); // NOI18N searchEditMenu.add(editMenuAddAuthorsToSelection); jSeparator1.setName("jSeparator1"); // NOI18N searchEditMenu.add(jSeparator1); editMenuManLinks.setAction(actionMap.get("addToManLinks")); // NOI18N editMenuManLinks.setName("editMenuManLinks"); // NOI18N searchEditMenu.add(editMenuManLinks); editMenuLuhmann.setAction(actionMap.get("addToLuhmann")); // NOI18N editMenuLuhmann.setName("editMenuLuhmann"); // NOI18N searchEditMenu.add(editMenuLuhmann); editMenuBookmarks.setAction(actionMap.get("addToBookmarks")); // NOI18N editMenuBookmarks.setName("editMenuBookmarks"); // NOI18N searchEditMenu.add(editMenuBookmarks); jSeparator6.setName("jSeparator6"); // NOI18N searchEditMenu.add(jSeparator6); editMenuDesktop.setAction(actionMap.get("addToDesktop")); // NOI18N editMenuDesktop.setName("editMenuDesktop"); // NOI18N searchEditMenu.add(editMenuDesktop); searchMenuBar.add(searchEditMenu); searchFilterMenu.setText(resourceMap.getString("searchFilterMenu.text")); // NOI18N searchFilterMenu.setName("searchFilterMenu"); // NOI18N filterSearch.setAction(actionMap.get("filterSearch")); // NOI18N filterSearch.setName("filterSearch"); // NOI18N searchFilterMenu.add(filterSearch); jSeparator14.setName("jSeparator14"); // NOI18N searchFilterMenu.add(jSeparator14); filterKeywords.setAction(actionMap.get("filterKeywords")); // NOI18N filterKeywords.setName("filterKeywords"); // NOI18N searchFilterMenu.add(filterKeywords); jSeparator15.setName("jSeparator15"); // NOI18N searchFilterMenu.add(jSeparator15); filterAuthors.setAction(actionMap.get("filterAuthors")); // NOI18N filterAuthors.setName("filterAuthors"); // NOI18N searchFilterMenu.add(filterAuthors); jSeparator23.setName("jSeparator23"); // NOI18N searchFilterMenu.add(jSeparator23); filterTopLevelLuhmann.setAction(actionMap.get("filterTopLevelLuhmann")); // NOI18N filterTopLevelLuhmann.setName("filterTopLevelLuhmann"); // NOI18N searchFilterMenu.add(filterTopLevelLuhmann); searchMenuBar.add(searchFilterMenu); searchSearchMenu.setText(resourceMap.getString("searchSearchMenu.text")); // NOI18N searchSearchMenu.setName("searchSearchMenu"); // NOI18N searchMenuSelectionContent.setAction(actionMap.get("newSearchFromSelection")); // NOI18N searchMenuSelectionContent.setName("searchMenuSelectionContent"); // NOI18N searchSearchMenu.add(searchMenuSelectionContent); jSeparator19.setName("jSeparator19"); // NOI18N searchSearchMenu.add(jSeparator19); searchMenuKeywordLogOr.setAction(actionMap.get("newSearchFromKeywordsLogOr")); // NOI18N searchMenuKeywordLogOr.setName("searchMenuKeywordLogOr"); // NOI18N searchSearchMenu.add(searchMenuKeywordLogOr); searchMenuKeywordLogAnd.setAction(actionMap.get("newSearchFromKeywordsLogAnd")); // NOI18N searchMenuKeywordLogAnd.setName("searchMenuKeywordLogAnd"); // NOI18N searchSearchMenu.add(searchMenuKeywordLogAnd); searchMenuKeywordLogNot.setAction(actionMap.get("newSearchFromKeywordsLogNot")); // NOI18N searchMenuKeywordLogNot.setName("searchMenuKeywordLogNot"); // NOI18N searchSearchMenu.add(searchMenuKeywordLogNot); searchMenuBar.add(searchSearchMenu); searchViewMenu.setText(resourceMap.getString("searchViewMenu.text")); // NOI18N searchViewMenu.setName("searchViewMenu"); // NOI18N viewMenuShowOnDesktop.setAction(actionMap.get("showEntryInDesktop")); // NOI18N viewMenuShowOnDesktop.setName("viewMenuShowOnDesktop"); // NOI18N searchViewMenu.add(viewMenuShowOnDesktop); jSeparator11.setName("jSeparator11"); // NOI18N searchViewMenu.add(jSeparator11); viewMenuHighlight.setAction(actionMap.get("toggleHighlightResults")); // NOI18N viewMenuHighlight.setSelected(true); viewMenuHighlight.setName("viewMenuHighlight"); // NOI18N searchViewMenu.add(viewMenuHighlight); viewMenuHighlightSettings.setAction(actionMap.get("showHighlightSettings")); // NOI18N viewMenuHighlightSettings.setName("viewMenuHighlightSettings"); // NOI18N searchViewMenu.add(viewMenuHighlightSettings); jSeparator9.setName("jSeparator9"); // NOI18N searchViewMenu.add(jSeparator9); viewMenuShowEntry.setAction(actionMap.get("showEntryImmediately")); // NOI18N viewMenuShowEntry.setSelected(true); viewMenuShowEntry.setName("viewMenuShowEntry"); // NOI18N searchViewMenu.add(viewMenuShowEntry); jSeparator7.setName("jSeparator7"); // NOI18N searchViewMenu.add(jSeparator7); jMenuItemSwitchLayout.setAction(actionMap.get("switchLayout")); // NOI18N jMenuItemSwitchLayout.setName("jMenuItemSwitchLayout"); // NOI18N searchViewMenu.add(jMenuItemSwitchLayout); jSeparator8.setName("jSeparator8"); // NOI18N searchViewMenu.add(jSeparator8); viewMenuFullScreen.setAction(actionMap.get("viewFullScreen")); // NOI18N viewMenuFullScreen.setName("viewMenuFullScreen"); // NOI18N searchViewMenu.add(viewMenuFullScreen); searchMenuBar.add(searchViewMenu); setJMenuBar(searchMenuBar); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(searchToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(searchMainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addComponent(searchStatusPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(searchToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(searchMainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGap(0, 0, 0) .addComponent(searchStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); pack(); }// </editor-fold>//GEN-END:initComponents /** * This variable indicates whether or not the fullscreen mode is supportet * on the current system. if not, disable related icons... */ private boolean fullScreenSupp = false; public boolean isFullScreenSupp() { return fullScreenSupp; } public void setFullScreenSupp(boolean b) { boolean old = isFullScreenSupp(); this.fullScreenSupp = b; firePropertyChange("fullScreenSupp", old, isFullScreenSupp()); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenuItem editMenuAddAuthorsToSelection; private javax.swing.JMenuItem editMenuAddKeywordsToSelection; private javax.swing.JMenuItem editMenuBookmarks; private javax.swing.JMenuItem editMenuCopy; private javax.swing.JMenuItem editMenuDelete; private javax.swing.JMenuItem editMenuDeleteEntry; private javax.swing.JMenuItem editMenuDesktop; private javax.swing.JMenuItem editMenuDuplicateEntry; private javax.swing.JMenuItem editMenuEditEntry; private javax.swing.JMenuItem editMenuFindReplace; private javax.swing.JMenuItem editMenuLuhmann; private javax.swing.JMenuItem editMenuManLinks; private javax.swing.JMenuItem editMenuSelectAll; private javax.swing.JMenuItem fileMenuClose; private javax.swing.JMenuItem fileMenuDeleteAll; private javax.swing.JMenuItem fileMenuDeleteSearch; private javax.swing.JMenuItem fileMenuDuplicateSearch; private javax.swing.JMenuItem fileMenuExport; private javax.swing.JMenuItem fileMenuLongDesc; private javax.swing.JMenuItem filterAuthors; private javax.swing.JMenuItem filterKeywords; private javax.swing.JMenuItem filterSearch; private javax.swing.JMenuItem filterTopLevelLuhmann; private javax.swing.JButton jButtonDeleteSearch; private javax.swing.JButton jButtonResetList; private javax.swing.JComboBox jComboBoxSearches; private javax.swing.JEditorPane jEditorPaneSearchEntry; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabelHits; private javax.swing.JList jListKeywords; private javax.swing.JMenuItem jMenuItemSwitchLayout; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel9; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane4; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator10; private javax.swing.JSeparator jSeparator11; private javax.swing.JToolBar.Separator jSeparator12; private javax.swing.JSeparator jSeparator13; private javax.swing.JSeparator jSeparator14; private javax.swing.JSeparator jSeparator15; private javax.swing.JSeparator jSeparator16; private javax.swing.JSeparator jSeparator19; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator20; private javax.swing.JSeparator jSeparator21; private javax.swing.JSeparator jSeparator22; private javax.swing.JPopupMenu.Separator jSeparator23; private javax.swing.JToolBar.Separator jSeparator3; private javax.swing.JSeparator jSeparator4; private javax.swing.JToolBar.Separator jSeparator5; private javax.swing.JSeparator jSeparator6; private javax.swing.JPopupMenu.Separator jSeparator7; private javax.swing.JPopupMenu.Separator jSeparator8; private javax.swing.JSeparator jSeparator9; private javax.swing.JSplitPane jSplitPaneSearch1; private javax.swing.JSplitPane jSplitPaneSearch2; private javax.swing.JTable jTableResults; private javax.swing.JTextField jTextFieldFilterList; private javax.swing.JMenu searchEditMenu; private javax.swing.JMenu searchFileMenu; private javax.swing.JMenu searchFilterMenu; private javax.swing.JPanel searchMainPanel; private javax.swing.JMenuBar searchMenuBar; private javax.swing.JMenuItem searchMenuKeywordLogAnd; private javax.swing.JMenuItem searchMenuKeywordLogNot; private javax.swing.JMenuItem searchMenuKeywordLogOr; private javax.swing.JMenuItem searchMenuSelectionContent; private javax.swing.JMenu searchSearchMenu; private javax.swing.JPanel searchStatusPanel; private javax.swing.JToolBar searchToolbar; private javax.swing.JMenu searchViewMenu; private javax.swing.JButton tb_bookmark; private javax.swing.JButton tb_copy; private javax.swing.JButton tb_desktop; private javax.swing.JButton tb_editentry; private javax.swing.JButton tb_highlight; private javax.swing.JButton tb_luhmann; private javax.swing.JButton tb_manlinks; private javax.swing.JButton tb_remove; private javax.swing.JButton tb_selectall; private javax.swing.JMenuItem viewMenuFullScreen; private javax.swing.JCheckBoxMenuItem viewMenuHighlight; private javax.swing.JMenuItem viewMenuHighlightSettings; private javax.swing.JCheckBoxMenuItem viewMenuShowEntry; private javax.swing.JMenuItem viewMenuShowOnDesktop; // End of variables declaration//GEN-END:variables private CHighlightSearchSettings highlightSettingsDlg; private CSearchDlg searchDlg; private TaskProgressDialog taskDlg; private CFilterSearch filterSearchDlg; private CRateEntry rateEntryDlg; }