Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ A lightweight and modern Markdown editor built with JavaFX.
- **Application Icon** - Custom SVG icon with PNG exports (16, 32, 64, 128 px) shown in the title bar, taskbar, and Alt+Tab switcher; on Linux the SVG is installed into `/usr/share/icons/hicolor/scalable/apps/` and the PNG-128 into `/usr/share/icons/hicolor/128x128/apps/` by the DEB post-install script; the `.desktop` entry includes `StartupWMClass=MarkNote` so GNOME Shell correctly associates running windows with the dock icon
- **Reading Mode** - Distraction-free fullscreen reading (`Ctrl+Shift+P` or **View → Enter Reading Mode**): the Preview panel fills the whole screen, the editor and all side panels are hidden; the Project Explorer reappears as a compact floating overlay with a **▾/▴ minimize toggle** to collapse it to its title bar; exiting restores all panels and split-divider positions exactly as they were before
- **View Menu Controls** - Toggle visibility of Project Explorer (`Ctrl+E`), Preview (`Ctrl+P`), Tag Cloud (`Ctrl+T`), Network Diagram (`Ctrl+L`), and **LLM Chat** (`Ctrl+M`) via the View menu; Show Welcome
- **Close Tab** - Close the active document tab with `Ctrl+W`
- **Close Tab** - Close the active document tab with `Ctrl+W`; close **all** tabs with `Ctrl+Shift+W`; right-click any tab for **Close All**, **Close All But This**, or **Close Tabs to the Left**

## Supported Languages

Expand Down
6 changes: 6 additions & 0 deletions src/docs/user-guide-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ MarkNote automatically remembers which documents you had open when you close a p
- Click on a tab to switch to that document
- Click the **×** button on a tab to close it
- Press `Ctrl+W` to close the active tab
- Press `Ctrl+Shift+W` to close **all** tabs at once
- **Right-click** on any tab for additional close actions:
- **Close All Tabs** — closes every open tab
- **Close All But This** — keeps only the tab you right-clicked
- **Close Tabs to the Left** — closes all tabs to the left of the current one
- **Drag tabs** to reorder them within the tab bar
- Modified documents show a **\*** prefix in the tab title
- Tab names longer than 15 characters are truncated with an ellipsis (`…`); hover for the full name
Expand Down Expand Up @@ -1463,6 +1468,7 @@ To change the language:
| `Ctrl+S` | Save |
| `Ctrl+Shift+S` | Save as |
| `Ctrl+W` | Close current tab |
| `Ctrl+Shift+W` | Close all tabs |
| `Ctrl+Q` | Quit application |

### Editing
Expand Down
66 changes: 59 additions & 7 deletions src/main/java/MarkNote.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import javafx.scene.image.Image;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Menu;
Expand Down Expand Up @@ -169,6 +170,15 @@ public void start(Stage stage) {
mainTabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.ALL_TABS);
mainTabPane.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);

// Attacher le menu contextuel à chaque onglet dès son ajout (tous types confondus)
mainTabPane.getTabs().addListener((javafx.collections.ListChangeListener<javafx.scene.control.Tab>) change -> {
while (change.next()) {
if (change.wasAdded()) {
change.getAddedSubList().forEach(this::installTabContextMenu);
}
}
});

// Panel de prévisualisation
previewPanel = new PreviewPanel();
previewPanel.setOnMarkdownLinkClick(this::openFileInTab);
Expand Down Expand Up @@ -466,9 +476,13 @@ private MenuBar createMenuBar() {
closeTabItem.setAccelerator(KeyCombination.keyCombination("Ctrl+W"));
closeTabItem.setOnAction(e -> closeActiveTab());

MenuItem closeAllTabsItem = new MenuItem(messages.getString("menu.file.closeAll"));
closeAllTabsItem.setAccelerator(KeyCombination.keyCombination("Ctrl+Shift+W"));
closeAllTabsItem.setOnAction(e -> closeAllTabs());

fileMenu.getItems().addAll(newDocItem, new SeparatorMenuItem(), openProjectItem, openItem,
new SeparatorMenuItem(), recentMenu, new SeparatorMenuItem(), saveItem, saveAsItem,
new SeparatorMenuItem(), closeTabItem, quitItem);
new SeparatorMenuItem(), closeTabItem, closeAllTabsItem, new SeparatorMenuItem(), quitItem);

// == Menu Affichage ==
Menu viewMenu = new Menu(messages.getString("menu.view"));
Expand Down Expand Up @@ -593,15 +607,53 @@ private void addNewDocument() {
private void closeActiveTab() {
var selected = mainTabPane.getSelectionModel().getSelectedItem();
if (selected != null) {
// Déclencher la logique de fermeture existante (onCloseRequest)
var closeEvent = new javafx.event.Event(javafx.scene.control.Tab.TAB_CLOSE_REQUEST_EVENT);
javafx.event.Event.fireEvent(selected, closeEvent);
if (!closeEvent.isConsumed()) {
mainTabPane.getTabs().remove(selected);
}
requestCloseTab(selected);
}
}

/** Déclenche l'événement de fermeture sur un onglet et le retire s'il n'est pas consommé. */
private void requestCloseTab(javafx.scene.control.Tab tab) {
var event = new javafx.event.Event(javafx.scene.control.Tab.TAB_CLOSE_REQUEST_EVENT);
javafx.event.Event.fireEvent(tab, event);
if (!event.isConsumed()) {
mainTabPane.getTabs().remove(tab);
}
}

/** Ferme tous les onglets. */
private void closeAllTabs() {
List.copyOf(mainTabPane.getTabs()).forEach(this::requestCloseTab);
}

/** Ferme tous les onglets sauf {@code referenceTab}. */
private void closeOtherTabs(javafx.scene.control.Tab referenceTab) {
List.copyOf(mainTabPane.getTabs()).stream()
.filter(t -> t != referenceTab)
.forEach(this::requestCloseTab);
}

/** Ferme tous les onglets situés à gauche de {@code referenceTab}. */
private void closeTabsToLeft(javafx.scene.control.Tab referenceTab) {
int refIndex = mainTabPane.getTabs().indexOf(referenceTab);
if (refIndex > 0) {
List.copyOf(mainTabPane.getTabs().subList(0, refIndex)).forEach(this::requestCloseTab);
}
}

/** Installe un menu contextuel sur un onglet avec les actions de fermeture groupée. */
private void installTabContextMenu(javafx.scene.control.Tab tab) {
MenuItem closeAllItem = new MenuItem(messages.getString("menu.file.closeAll"));
closeAllItem.setOnAction(e -> closeAllTabs());

MenuItem closeOthersItem = new MenuItem(messages.getString("menu.tab.closeOthers"));
closeOthersItem.setOnAction(e -> closeOtherTabs(tab));

MenuItem closeToLeftItem = new MenuItem(messages.getString("menu.tab.closeToLeft"));
closeToLeftItem.setOnAction(e -> closeTabsToLeft(tab));

tab.setContextMenu(new ContextMenu(closeAllItem, new SeparatorMenuItem(), closeOthersItem, closeToLeftItem));
}

/**
* Affiche l'onglet Welcome avec la liste des projets récents.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Diagramme réseau
menu.view.showWelcome=Afficher Welcome
menu.view.console=Debug Console
menu.file.close=Fermer l'onglet
menu.file.closeAll=Fermer tous les onglets
menu.tab.closeOthers=Fermer tous sauf celui-ci
menu.tab.closeToLeft=Fermer les onglets à gauche

# Menu Aide
menu.help=Aide
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Netzwerkdiagramm
menu.view.showWelcome=Willkommen anzeigen
menu.view.console=Debug-Konsole
menu.file.close=Tab schließen
menu.file.closeAll=Alle Tabs schließen
menu.tab.closeOthers=Alle anderen Tabs schließen
menu.tab.closeToLeft=Tabs links schließen

# Hilfe-Menü
menu.help=Hilfe
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Network diagram
menu.view.showWelcome=Show Welcome
menu.view.console=Debug Console
menu.file.close=Close tab
menu.file.closeAll=Close All Tabs
menu.tab.closeOthers=Close All But This
menu.tab.closeToLeft=Close Tabs to the Left

# Help Menu
menu.help=Help
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Diagrama de red
menu.view.showWelcome=Mostrar Bienvenida
menu.view.console=Consola de depuración
menu.file.close=Cerrar pestaña
menu.file.closeAll=Cerrar todas las pestañas
menu.tab.closeOthers=Cerrar todas menos esta
menu.tab.closeToLeft=Cerrar pestañas a la izquierda

# Menú Ayuda
menu.help=Ayuda
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Diagramme réseau
menu.view.showWelcome=Afficher Welcome
menu.view.console=Console de débogage
menu.file.close=Fermer l'onglet
menu.file.closeAll=Fermer tous les onglets
menu.tab.closeOthers=Fermer tous sauf celui-ci
menu.tab.closeToLeft=Fermer les onglets à gauche

# Menu Aide
menu.help=Aide
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/i18n/messages_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ menu.view.networkDiagram=Diagramma di rete
menu.view.showWelcome=Mostra Benvenuto
menu.view.console=Console di debug
menu.file.close=Chiudi scheda
menu.file.closeAll=Chiudi tutte le schede
menu.tab.closeOthers=Chiudi tutte tranne questa
menu.tab.closeToLeft=Chiudi schede a sinistra

# Menu Aiuto
menu.help=Aiuto
Expand Down
Loading