Final fixes completed; recently opened files can now be selected from

Jskad's file menu.
This commit is contained in:
dchandler 2003-07-05 02:15:33 +00:00
parent 4410b52c07
commit 51679c158b
3 changed files with 180 additions and 63 deletions

View file

@ -18,6 +18,13 @@
######################### User Preferences ###########################
############################################################################
# How many recently opened files should be displayed?
thdl.number.of.recently.opened.files.to.show = 4
# How many characters maximum do you want to show on the File menu for
# a recently opened file?
thdl.max.chars.in.recently.opened.file.name = 40
# Set this to the full path of the user preferences file, or to the
# empty string if you wish to use the default values, which are
# system-specific.

View file

@ -126,25 +126,10 @@ public class Jskad extends JPanel implements DocumentListener {
/** Do not use this JPanel constructor. */
private Jskad(LayoutManager lm, boolean isDB) { super(lm, isDB); }
/** Tells ThdlOptions about the recently opened files. */
// DLC FIXME: this doesn't keep the second-most recently opened item second if you have just three items.
private static void storeRecentlyOpenedFilePreferences() {
int N = ThdlOptions.getIntegerOption("thdl.number.of.recently.opened.files.to.show", 4);
int n = 0;
// We store 2*N files in the preferences in case some are deleted.
for (int k = recentlyOpenedFiles.size(); k > 0 && n < 2*N; k--) {
File f = (File)recentlyOpenedFiles.elementAt(k - 1);
if (f.isFile()) {
ThdlOptions.setUserPreference("thdl.recently.opened.file." + n++,
f.getAbsolutePath());
}
}
}
/** Saves user preferences to disk if possible. */
private void savePreferencesAction() {
try {
storeRecentlyOpenedFilePreferences();
RecentlyOpenedFilesDatabase.storeRecentlyOpenedFilePreferences();
if (!ThdlOptions.saveUserPreferences()) {
JOptionPane.showMessageDialog(Jskad.this,
@ -178,43 +163,14 @@ public class Jskad extends JPanel implements DocumentListener {
/** pane displaying Jskad's single HTML help file */
private static HTMLPane helpPane;
/** Returns the <code>n</code>th most recently opened file, given
that we care about <code>N</code> recently opened files in
total. When <code>n</code> is zero, the most recently opened
file is returned. This file does exist. Returns null if we
haven't kept track of enough files to say. */
private static File getNthRecentlyOpenedFile(int n, int N) {
for (int i = n; i < N*2; i++) {
String x = ThdlOptions.getStringOption("thdl.recently.opened.file." + i);
if (null == x)
return null;
File f = new File(x);
if (f.isFile())
return f;
}
return null;
}
/** a vector with the most recently opened file at its end. */
private static Vector recentlyOpenedFiles = new Vector();
/** the File menu */
private JMenu fileMenu = null;
private static void addMostRecentlyOpenedFile(File fileChosen) {
// the last element is the most recently opened.
int index = recentlyOpenedFiles.indexOf(fileChosen);
if (index > -1) {
recentlyOpenedFiles.remove(index);
}
recentlyOpenedFiles.add(fileChosen);
}
/** Updates state information now that we know that fileChosen is
the most recently opened file. */
private static void noteMostRecentlyOpenedFile(File fileChosen) {
addMostRecentlyOpenedFile(fileChosen);
storeRecentlyOpenedFilePreferences();
RecentlyOpenedFilesDatabase.setMostRecentlyOpenedFile(fileChosen);
int i, sz = jskads.size();
for (i = 0; i < sz; i++) {
((Jskad)jskads.elementAt(i)).updateRecentlyOpenedFilesMenuItems();
@ -225,21 +181,20 @@ public class Jskad extends JPanel implements DocumentListener {
int ic = fileMenu.getItemCount();
while (fileMenu.getItemCount() > 8)
fileMenu.remove(7);
int N = ThdlOptions.getIntegerOption("thdl.number.of.recently.opened.files.to.show", 4);
int N = RecentlyOpenedFilesDatabase.getNumberOfFilesToShow();
// Avoid adding duplicate entries:
int maximum = recentlyOpenedFiles.size();
if (N > maximum) N = maximum;
boolean addedSeparator = false;
for (int i = 0; i < N; i++) {
final File recentlyOpenedFile
= getNthRecentlyOpenedFile(N-i-1, N);
= RecentlyOpenedFilesDatabase.getNthRecentlyOpenedFile(N-i-1);
if (null != recentlyOpenedFile) {
if (!addedSeparator) {
fileMenu.insertSeparator(6);
addedSeparator = true;
}
JMenuItem item = new JMenuItem((N-i) + " " + recentlyOpenedFile.getAbsolutePath());
JMenuItem item = new JMenuItem((N-i) + " "
+ RecentlyOpenedFilesDatabase.getLabel(recentlyOpenedFile));
item.addActionListener(new ThdlActionListener() {
public void theRealActionPerformed(ActionEvent e) {
openFile(recentlyOpenedFile);
@ -274,7 +229,11 @@ public class Jskad extends JPanel implements DocumentListener {
= ThdlOptions.getStringOption("thdl.Jskad.working.directory",
null);
fileChooser
= new JFileChooser(whereToStart.equals("") ? null : whereToStart);
= new JFileChooser((whereToStart == null)
? null
: (whereToStart.equals("")
? null
: whereToStart));
rtfFilter = new RTFFilter();
txtFilter = new TXTFilter();
fileChooser.addChoosableFileFilter(rtfFilter);
@ -339,14 +298,6 @@ public class Jskad extends JPanel implements DocumentListener {
});
fileMenu.add(saveAsItem);
// Add the N most recently opened files.
int N = ThdlOptions.getIntegerOption("thdl.number.of.recently.opened.files.to.show", 4);
int maxCharsToShow
= ThdlOptions.getIntegerOption("thdl.max.chars.in.recently.opened.file.name", 35);
for (int i = 0; i < 2*N; i++) {
addMostRecentlyOpenedFile(getNthRecentlyOpenedFile(i, N));
}
if (parentObject instanceof JFrame) {
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ThdlActionListener() {
@ -941,8 +892,12 @@ public class Jskad extends JPanel implements DocumentListener {
String whereToStart
= ThdlOptions.getStringOption("thdl.Jskad.working.directory",
null);
fileChooser
= new JFileChooser(whereToStart.equals("") ? null : whereToStart);
fileChooser
= new JFileChooser((whereToStart == null)
? null
: (whereToStart.equals("")
? null
: whereToStart));
fileChooser.addChoosableFileFilter(rtfFilter);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

View file

@ -0,0 +1,155 @@
/*
The contents of this file are subject to the THDL Open Community License
Version 1.0 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License on the THDL web site
(http://www.thdl.org/).
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific terms governing rights and limitations under the
License.
The Initial Developer of this software is the Tibetan and Himalayan Digital
Library (THDL). Portions created by the THDL are Copyright 2003 THDL.
All Rights Reserved.
Contributor(s): ______________________________________.
*/
package org.thdl.tib.input;
import org.thdl.util.ThdlOptions;
import java.util.Vector;
import java.io.File;
/** A database of the files most recently opened in Jskad. The client
must call {@link #storeRecentlyOpenedFilePreferences()} before
exiting.
@author David Chandler
*/
class RecentlyOpenedFilesDatabase {
/** Tells ThdlOptions about the recently opened files. Call this before program exit. */
// DLC FIXME: this doesn't keep the second-most recently opened item second if you have just three items.
public static void storeRecentlyOpenedFilePreferences() {
int n = 0;
// We store 2*N files in the preferences in case some are deleted.
for (int k = 0; k < recentlyOpenedFiles.size() && n < 2*N; k++) {
File f = (File)recentlyOpenedFiles.elementAt(k);
if (f.isFile()) {
ThdlOptions.setUserPreference("thdl.recently.opened.file." + n++,
f.getAbsolutePath());
}
}
}
/** the number of recently opened files to display on the File
menu */
private static int N;
/** the maximum number of characters to display in a label shown
to the user for a recently opened file */
private static int maxCharsToShow;
/** Returns the maximum number of recently opened files that the
user wishes to see in the File menu. */
public static int getNumberOfFilesToShow() {
if (uninitialized) init();
return N;
}
/** false iff we are in the process of initializing or have
already initialized */
private static boolean uninitialized = true;
/** Reads the user's preferences and fills in {@link
#recentlyOpenedFiles} based on them. */
private static void init() {
if (uninitialized) {
uninitialized = false; // must come first!
maxCharsToShow
= ThdlOptions.getIntegerOption("thdl.max.chars.in.recently.opened.file.name", 40);
N = ThdlOptions.getIntegerOption("thdl.number.of.recently.opened.files.to.show", 4);
// Add the N most recently opened files.
if (maxCharsToShow < 5)
maxCharsToShow = 5;
for (int i = 2*N - 1; i >= 0; i--) {
setMostRecentlyOpenedFile(getNthRecentlyOpenedFileFromPreferences(i));
}
}
}
/** Returns the <code>n</code>th most recently opened file, given
that we care about <code>N</code> recently opened files in
total. When <code>n</code> is zero, the most recently opened
file is returned. This file does exist. Returns null if we
haven't kept track of enough files to say. */
public static File getNthRecentlyOpenedFile(int n) {
if (uninitialized) init();
while (n < recentlyOpenedFiles.size()) {
File f = (File)recentlyOpenedFiles.elementAt(n);
if (f.isFile())
return f;
++n;
}
return null;
}
/** Returns the nth most recently opened, existing file listed in
the user's preferences. Returns null if their preferences do
not contain n+1 existing files. */
private static File getNthRecentlyOpenedFileFromPreferences(int n) {
if (uninitialized) init();
for (int i = n; i < N*2; i++) {
String x = ThdlOptions.getStringOption("thdl.recently.opened.file." + i);
if (null == x)
return null;
File f = new File(x);
if (f.isFile())
return f;
}
return null;
}
/** Notes the fact that fileChosen was the file most recently
opened by Jskad. */
public static void setMostRecentlyOpenedFile(File fileChosen) {
if (null != fileChosen) {
if (uninitialized) init();
// the first element is the most recently opened.
int index = recentlyOpenedFiles.indexOf(fileChosen);
if (index > -1) {
recentlyOpenedFiles.remove(index);
}
recentlyOpenedFiles.add(0, fileChosen);
}
}
/** a vector with the most recently opened file at its
beginning, the least recently opened at its end. */
private static Vector recentlyOpenedFiles = new Vector();
/** Prints debugging information to System.err. */
public static void printDebuggingInfo() {
if (uninitialized) init();
System.err.println("<RecentlyOpenedFilesDatabase>");
for (int i = 0; i < recentlyOpenedFiles.size(); i++)
System.err.println("File " + i + " (where 0 is most recent) is " + ((File)recentlyOpenedFiles.elementAt(i)).getAbsolutePath());
System.err.println("</RecentlyOpenedFilesDatabase>");
}
/** Returns a user-friendly label for f that is not longer than
the user's preferences allow. */
public static String getLabel(File f) {
if (uninitialized) init();
String path = f.getAbsolutePath();
int l;
if ((l = path.length()) <= maxCharsToShow)
return path;
return "..." + path.substring(l - maxCharsToShow + 3);
}
}