diff --git a/src/main/java/de/danielluedecke/zettelkasten/CImportBibTex.java b/src/main/java/de/danielluedecke/zettelkasten/CImportBibTex.java index a9665034..2f930e01 100644 --- a/src/main/java/de/danielluedecke/zettelkasten/CImportBibTex.java +++ b/src/main/java/de/danielluedecke/zettelkasten/CImportBibTex.java @@ -739,7 +739,7 @@ protected Object doInBackground() { // only create content/new entry, if any abstract was found... if (content != null && !content.isEmpty()) { // finally, add entry to dataset - dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); + dataObj.addEntryFromBibTeX("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and increase entry counter newEntries++; } // if nothing found, add at least the keywords @@ -816,7 +816,7 @@ else if (keywords != null && keywords.length > 0) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // finally, add entry to dataset - dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); + dataObj.addEntryFromBibTeX("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and delete BibTeX attribute from the *old* entry... dataObj.setContentFromBibTexRemark(counter, false); // update found-variable @@ -877,7 +877,7 @@ else if (keywords != null && keywords.length > 0) { keywords = (jRadioButtonSourceDB.isSelected()) ? bibtexObj.getKeywords(bibkey.toString()) : bibtexObj.getKeywordsFromAttachedFile(bibkey.toString()); } // finally, add entry to dataset - dataObj.addEntryFromBibTex("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); + dataObj.addEntryFromBibTeX("", content, new String[]{au.toString()}, keywords, Tools.getTimeStamp()); // and increase entry counter newEntries++; } diff --git a/src/main/java/de/danielluedecke/zettelkasten/ZettelkastenView.java b/src/main/java/de/danielluedecke/zettelkasten/ZettelkastenView.java index a054e44e..ecb045e1 100644 --- a/src/main/java/de/danielluedecke/zettelkasten/ZettelkastenView.java +++ b/src/main/java/de/danielluedecke/zettelkasten/ZettelkastenView.java @@ -2734,7 +2734,7 @@ public final void updateDisplay(UpdateDisplayOptions options) { } /** - * Changes the text in the application's titlebar, by adding the filename of the + * Changes the text in the application's title bar, by adding the filename of the * currently opened file to it. */ private void updateFrameTitle() { @@ -8801,8 +8801,8 @@ private boolean loadMainDataZipDocument(File filepath, Daten daten, Bookmarks bo /** * load the document by opening a modal dialog, which opens the data via a - * background task. the dialog only displays a progressbar and an animated - * busyicon while opening the file, no user-interaction possible....
+ * background task. the dialog only displays a progress bar and an animated + * busy icon while opening the file, no user-interaction possible....
*
* We have this part of code "outsourced" into an own method because we need * this more often, e.g. when automatically loading the data at program diff --git a/src/main/java/de/danielluedecke/zettelkasten/database/Daten.java b/src/main/java/de/danielluedecke/zettelkasten/database/Daten.java index b441b5ec..d53a100d 100644 --- a/src/main/java/de/danielluedecke/zettelkasten/database/Daten.java +++ b/src/main/java/de/danielluedecke/zettelkasten/database/Daten.java @@ -38,6 +38,7 @@ import de.danielluedecke.zettelkasten.history.History; import de.danielluedecke.zettelkasten.settings.Settings; import de.danielluedecke.zettelkasten.util.classes.Comparer; +import de.danielluedecke.zettelkasten.view.Display; import de.danielluedecke.zettelkasten.util.Constants; import de.danielluedecke.zettelkasten.util.HtmlUbbUtil; import de.danielluedecke.zettelkasten.util.Tools; @@ -133,7 +134,7 @@ public class Daten { * previously accessed entries and so on... */ //private int[] history; - private History history; + private History history = new History(); /** * Stores the files which we want to retrieve from the main data file @@ -2923,7 +2924,7 @@ public int addEntry(String title, String content, String[] authors, String[] key this.activatedEntryNumber = getCount(ZKNCOUNT); } // and add the new position to the history... - addToHistory(); + addToHistory(activatedEntryNumber); // set modified state setModified(true); } catch (IllegalAddException | IllegalDataException ex) { @@ -3032,7 +3033,7 @@ public int addEntry(String title, String content, String[] authors, String[] key * {@link #ADD_LUHMANNENTRY_ERR ADD_LUHMANNENTRY_ERR} if an error * occured when adding a follower-entry (trailing entry) */ - public int addEntryFromBibTex(String title, String content, String[] authors, String[] keywords, String timestamp) { + public int addEntryFromBibTeX(String title, String content, String[] authors, String[] keywords, String timestamp) { // add entry int succeeded = addEntry(title, content, authors, keywords, "", null, timestamp, -1, false, -1); // if operation was successful... @@ -3308,7 +3309,7 @@ public boolean changeEntry(String title, String content, String[] authors, Strin // update the current zettel-position this.activatedEntryNumber = entrynumber; // and add the new position to the history... - addToHistory(); + addToHistory(activatedEntryNumber); // set modified state setModified(true); } catch (IllegalAddException | IllegalDataException ex) { @@ -4965,12 +4966,7 @@ public int getCount(int what) { /** * This method adds the new zettel-position to the history, so the user can go * back and fore to previous selected entries. - */ - private void addToHistory() { - addToHistory(activatedEntryNumber); - } - - + */ public void addToHistory(int entryNr) { history.addToHistory(entryNr); } @@ -5014,7 +5010,7 @@ public boolean activateEntry(int entryNumber) { activatedEntryNumber = entryNumber; // Update history with the new activated entry - addToHistory(); + addToHistory(activatedEntryNumber); return true; } @@ -5030,7 +5026,7 @@ public void nextEntry() { activatedEntryNumber = 1; } // update History - addToHistory(); + addToHistory(activatedEntryNumber); } /** @@ -5044,7 +5040,7 @@ public void prevEntry() { activatedEntryNumber = getCount(ZKNCOUNT); } // update History - addToHistory(); + addToHistory(activatedEntryNumber); } /** @@ -5055,7 +5051,7 @@ public void firstEntry() { // set counter for currently display entry to 1 activatedEntryNumber = 1; // update History - addToHistory(); + addToHistory(activatedEntryNumber); } /** @@ -5066,7 +5062,7 @@ public void lastEntry() { // set counter for currently display entry to last element activatedEntryNumber = getCount(ZKNCOUNT); // update History - addToHistory(); + addToHistory(activatedEntryNumber); } /** @@ -5076,7 +5072,7 @@ public void lastEntry() { * * It adds a the new entry (first parent entry) to the history. */ - public void goToFirstParentEntry() { + public void goToFirstTopOfTopic() { // was: goToFirstParentEntry ; cf. "Inhaltlich-logische Navigation" in https://niklas-luhmann-archiv.de/bestand/zettelkasten/tutorial int firstParentEntry = findParentlLuhmann(activatedEntryNumber, /* firstParent= */true); if (firstParentEntry == -1) { // No valid parent entry, do nothing. @@ -5087,7 +5083,7 @@ public void goToFirstParentEntry() { activatedEntryNumber = firstParentEntry; // Update history. - addToHistory(); + addToHistory(activatedEntryNumber); } /** @@ -7484,50 +7480,25 @@ public boolean isTopLevelLuhmann(int nr) { * {@code -1} if the entry {@code nr} has no luhmann (follower) parent, * resp. if the entry {@code nr} also has no follower entries. */ - public int findParentlLuhmann(int nr, boolean firstParent) { - // init find value - boolean found = true; - // - int retval = -1; - // - while (found) { - // indicates, whether any luhmann parent was found - boolean innerLoopFound = false; - // counter for looping through entries - int cnt = 1; - // get current entry number as string - String currentEntry = String.valueOf(nr); - // go through complete data set - while (!innerLoopFound && cnt <= getCount(Daten.ZKNCOUNT)) { - // get the luhmann numbers of each entry - String[] lnrs = getSubEntriesCsv(cnt).split(","); - // now check each number for the occurrence of the current entry number - for (String l : lnrs) { - // when one of the luhmann numbers equals the current entry number... - if (l.equals(currentEntry)) { - // we found a parent - nr = retval = cnt; - // find only first parent? - if (firstParent) { - return retval; - } - // indicate that parent was found - innerLoopFound = true; - break; - } + public int findParentLuhmann(int entryNumber, boolean firstParent) { + int parentNumber = -1; + + for (int currentEntry = 1; currentEntry <= getCount(Daten.ZKNCOUNT); currentEntry++) { + String subEntriesCsv = getSubEntriesCsv(currentEntry); + String[] subEntries = subEntriesCsv.split(","); + + if (Arrays.asList(subEntries).contains(String.valueOf(entryNumber))) { + parentNumber = currentEntry; + if (firstParent) { + break; // Found the first parent, so exit loop } - // increase loop counter - cnt++; - } - // when all entries have been checked and no parent was found - // leave complete routine and return result. - if (!innerLoopFound) { - found = false; } } - return retval; + + return parentNumber; } + /** * This method retrieves all follower and follower's follower of the entry * {@code zettelpos} and stores the index numbers in the global integer array diff --git a/src/main/java/de/danielluedecke/zettelkasten/history/History.java b/src/main/java/de/danielluedecke/zettelkasten/history/History.java index bbf0867e..e5919c1d 100644 --- a/src/main/java/de/danielluedecke/zettelkasten/history/History.java +++ b/src/main/java/de/danielluedecke/zettelkasten/history/History.java @@ -2,93 +2,128 @@ import de.danielluedecke.zettelkasten.util.Constants; import de.danielluedecke.zettelkasten.view.Display; -import ch.dreyeck.zettelkasten.xml.Zettel; /** * Manages the history of entries in the program. */ public class History implements HistoryNavigationListener { - private static final int HISTORY_MAX = 100; // Adjust as needed - private int[] history; - private int historyPosition; - private int historyCount; - private int activatedEntryNumber; - private Display display; - - public History(Display display) { - this.history = new int[HISTORY_MAX]; - this.historyPosition = -1; // Initialize to -1 to indicate no history yet - this.historyCount = 0; - this.display = display; - } - - /** - * Adds the given entry number to the history if a Zettel is displayed. - * - * @param entryNr the number of the entry to be added to the history - */ - public void addToHistory(int entryNr) { - Zettel currentZettel = display.getDisplayedZettel(); - if (currentZettel == null) { - Constants.zknlogger.info("No Zettel displayed. Entry not added to history: " + entryNr); - return; - } - - // Avoid duplicates - if (historyPosition >= 0 && history[historyPosition] == entryNr) { - return; - } - - if (historyPosition < HISTORY_MAX - 1) { - history[++historyPosition] = entryNr; - } else { - System.arraycopy(history, 1, history, 0, HISTORY_MAX - 1); - history[HISTORY_MAX - 1] = entryNr; - historyPosition = HISTORY_MAX - 1; - } - historyCount = Math.min(historyCount + 1, HISTORY_MAX); - activatedEntryNumber = entryNr; // Update activated entry number - Constants.zknlogger.info("Added to history: " + entryNr); - } - - public boolean canHistoryBack() { - return (historyPosition > 0); - } - - public boolean canHistoryFore() { - return (historyPosition >= 0 && historyPosition < (historyCount - 1)); - } - - public int historyBack() { - if (canHistoryBack()) { - activatedEntryNumber = history[--historyPosition]; - } - return activatedEntryNumber; - } - - public int historyFore() { - if (canHistoryFore()) { - activatedEntryNumber = history[++historyPosition]; - } - return activatedEntryNumber; - } - - @Override - public int navigateForwardInHistory() { - return historyFore(); - } - - @Override - public void navigateBackwardInHistory() { - historyBack(); - } - - // Getters for testing purposes - public int getHistoryCount() { - return historyCount; - } - - public int[] getHistory() { - return history; - } -} + private static final int HISTORY_MAX = 100; // Adjust as needed + private int[] history; + private int historyPosition; + private int historyCount; + private int activatedEntryNumber; + private int[] displayedEntries; + private int displayedCount; + + // Constructor without parameters + public History() { + this.history = new int[HISTORY_MAX]; + this.displayedEntries = new int[HISTORY_MAX]; // Initialize displayedEntries array + this.historyPosition = -1; + this.historyCount = 0; + this.displayedCount = 0; // Initialize displayedCount + } + + public History(Display display) { + this.history = new int[HISTORY_MAX]; + this.historyPosition = -1; // Initialize to -1 to indicate no history yet + this.historyCount = 0; + } + + /** + * Adds the given entry number to the history. + * + * @param entryNr the number of the entry to be added to the history + */ + public void addToHistory(int entryNr) { + // Log the current history before adding the new entry + logCurrentHistory(); + + // Avoid duplicates in history + if (historyPosition >= 0 && history[historyPosition] == entryNr) { + return; + } + + if (historyPosition < HISTORY_MAX - 1) { + history[++historyPosition] = entryNr; + } else { + System.arraycopy(history, 1, history, 0, HISTORY_MAX - 1); + history[HISTORY_MAX - 1] = entryNr; + historyPosition = HISTORY_MAX - 1; + } + historyCount = Math.min(historyCount + 1, HISTORY_MAX); + + // Log the added entry to history + Constants.zknlogger.info("Added to history: " + entryNr); + } + + /** + * Logs the current history. + */ + private void logCurrentHistory() { + StringBuilder historyBuilder = new StringBuilder("Current history: ["); + for (int i = 0; i <= historyPosition; i++) { + historyBuilder.append(history[i]); + if (i < historyPosition) { + historyBuilder.append(", "); + } + } + historyBuilder.append("]"); + Constants.zknlogger.info(historyBuilder.toString()); + } + + + /** + * Checks if history back navigation is possible. + * + * @return {@code true} if history back navigation is enabled, {@code false} + * otherwise + */ + public boolean canHistoryBack() { + return (historyPosition > 0); + } + + /** + * Checks if history forward navigation is possible. + * + * @return {@code true} if history forward navigation is enabled, {@code false} + * otherwise + */ + public boolean canHistoryFore() { + return (historyPosition >= 0 && historyPosition < (historyCount - 1)); + } + + /** + * Moves back through the history and returns the activated entry number. + * + * @return the activated entry number after navigating back in history + */ + public int historyBack() { + if (canHistoryBack()) { + activatedEntryNumber = history[--historyPosition]; + } + return activatedEntryNumber; + } + + /** + * Moves forward through the history and returns the activated entry number. + * + * @return the activated entry number after navigating forward in history + */ + public int historyFore() { + if (canHistoryFore()) { + activatedEntryNumber = history[++historyPosition]; + } + return activatedEntryNumber; + } + + @Override + public int navigateForwardInHistory() { + return historyFore(); + } + + @Override + public void navigateBackwardInHistory() { + historyBack(); + } +} \ No newline at end of file diff --git a/src/test/java/de/danielluedecke/zettelkasten/database/DatenTest.java b/src/test/java/de/danielluedecke/zettelkasten/database/DatenTest.java index 880673c6..bd5fcdf4 100644 --- a/src/test/java/de/danielluedecke/zettelkasten/database/DatenTest.java +++ b/src/test/java/de/danielluedecke/zettelkasten/database/DatenTest.java @@ -38,17 +38,17 @@ public void setUp() throws JDOMException, IOException { } @Test - void testGoToFirstParentEntryParent() { - // daten by default has current entry == 1. - Daten daten = new Daten(document); + void testGoToFirstTopOfTopic() { + // data by default has current entry == 1. + Daten data = new Daten(document); // The first (and only) parent of entry 1 is entry 2. - daten.goToFirstParentEntry(); - assertEquals(daten.getActivatedEntryNumber(), 2); + data.goToFirstTopOfTopic(); + assertEquals(data.getActivatedEntryNumber(), 2); // Entry 2 doesn't have a parent. Keep at the same Zettel number. - daten.goToFirstParentEntry(); - assertEquals(daten.getActivatedEntryNumber(), 2); + data.goToFirstTopOfTopic(); + assertEquals(data.getActivatedEntryNumber(), 2); } @Test diff --git a/src/test/java/de/danielluedecke/zettelkasten/database/DatenTestNG.java b/src/test/java/de/danielluedecke/zettelkasten/database/DatenTestNG.java new file mode 100644 index 00000000..e3c4adc3 --- /dev/null +++ b/src/test/java/de/danielluedecke/zettelkasten/database/DatenTestNG.java @@ -0,0 +1,44 @@ +package de.danielluedecke.zettelkasten.database; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.jdom2.Document; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +public class DatenTestNG { + + public Document document; + + @BeforeMethod + public void setUp() throws JDOMException, IOException { + String xmlString = "" + + "" + "" + + "Verschlagwortung und alphanumerische anstatt thematische Ordnung" + "" + + "1" + "1,2,1216,1983" + "" + "" + + "feste Stellordnung" + "4,10,61,161,1771,3622" + "" + + "" + "Zettel entry that is the first parent of the Zettel entry #1" + + "" + "" + "" + "" + "" + "" + + "1" + "" + "" + + "Zettel entry that is not connected to any of the others" + "" + + "" + "" + "" + "" + "" + "" + + "" + ""; + SAXBuilder builder = new SAXBuilder(); + document = builder.build(new ByteArrayInputStream(xmlString.getBytes())); + } + + @Test + public void testFindParentLuhmannFirstParentTrue() { + Daten daten = new Daten(document); + + // Test for first parent + int result = daten.findParentLuhmann(1, true); + assertEquals(result, 2, "First parent of entry 1 should be entry 2"); + } +} diff --git a/src/test/java/de/danielluedecke/zettelkasten/database/Entry.java b/src/test/java/de/danielluedecke/zettelkasten/database/Entry.java new file mode 100644 index 00000000..9c5eb518 --- /dev/null +++ b/src/test/java/de/danielluedecke/zettelkasten/database/Entry.java @@ -0,0 +1,26 @@ +package de.danielluedecke.zettelkasten.database; + +import java.util.*; + +public class Entry { + private int number; + private List subEntries; + + public Entry(int number) { + this.number = number; + this.subEntries = new ArrayList<>(); + } + + public void addSubEntry(int subEntryNumber) { + this.subEntries.add(subEntryNumber); + } + + public int getNumber() { + return number; + } + + public List getSubEntries() { + return subEntries; + } +} +