režimy zamykání: v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 24 Dec 2023 00:38:41 +0100
branchv_0
changeset 42d2414701ce09
parent 41 64e564c2f069
child 43 d65966d31bbd
režimy zamykání:

- vypnuté: tlačítko pro zamykání je skryté a soubor se nezamyká
- volitelné: uživatel může soubor zamknout, ale může editovat i bez toho
- povinné: uživatel musí soubor zamknout, aby mohl atributy editovat

Změny v atributech se vždy propisují okamžitě - na ně zámek nemá vliv.
Zámek je na souboru (ne metadatech) a slouží pro kooperující procesy.
Proces, který soubor/metadata čte, si jednak může soubor zamknout (POSIX)
a tím mít jistotu, že zrovna neprobíhá editace.
A jednak může reagovat na notifikace CLOSE_WRITE (inotify).
Notifikaci mu pošleme tím, že soubor odemkneme (čímž se i zavře).
src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java
src/main/java/cz/frantovo/rozsireneatributy/Konfigurace.java
src/main/java/cz/frantovo/rozsireneatributy/gui/Panel.java
src/main/resources/cz/frantovo/rozsireneatributy/Překlady_cs.properties
src/main/resources/cz/frantovo/rozsireneatributy/Překlady_en.properties
     1.1 --- a/src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java	Tue Dec 19 00:47:41 2023 +0100
     1.2 +++ b/src/main/java/cz/frantovo/rozsireneatributy/CLIParser.java	Sun Dec 24 00:38:41 2023 +0100
     1.3 @@ -18,6 +18,7 @@
     1.4  
     1.5  import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceAtributu;
     1.6  import cz.frantovo.rozsireneatributy.Konfigurace.DefiniceHodnoty;
     1.7 +import cz.frantovo.rozsireneatributy.Konfigurace.RežimZamykání;
     1.8  import java.io.File;
     1.9  import java.util.Arrays;
    1.10  import java.util.Collection;
    1.11 @@ -60,8 +61,8 @@
    1.12  
    1.13  		if (k.getSoubor() == null)
    1.14  			throw new CLIParserException(
    1.15 -					překlady.getString("chyba.cli.chybíSoubor"));
    1.16 -		
    1.17 +				překlady.getString("chyba.cli.chybíSoubor"));
    1.18 +
    1.19  		return k;
    1.20  	}
    1.21  
    1.22 @@ -101,12 +102,17 @@
    1.23  				return index - originalIndex;
    1.24  			}
    1.25  		},
    1.26 -		POVINNÉ_ZAMYKÁNÍ("--povinné-zamykání", "--mandatory-locking") {
    1.27 +		REŽIM_ZAMYKÁNÍ("--režim-zamykání", "--locking-mode") {
    1.28  			@Override
    1.29  			public int parsuj(String[] parametry, int index, Konfigurace k)
    1.30  				throws CLIParserException {
    1.31  				int originalIndex = index;
    1.32 -				k.setPovinnéZamykání(načtiDalšíBoolean(parametry, ++index));
    1.33 +				String hodnota = načtiDalší(parametry, ++index);
    1.34 +				k.setRežimZamykání(RežimZamykání.najdiRežim(hodnota));
    1.35 +				if (k.getRežimZamykání() == null)
    1.36 +					throw new CLIParserException(
    1.37 +						// TODO: překlad:
    1.38 +						"Neplatný režim zamykání: " + hodnota);
    1.39  				return index - originalIndex;
    1.40  			}
    1.41  		},
     2.1 --- a/src/main/java/cz/frantovo/rozsireneatributy/Konfigurace.java	Tue Dec 19 00:47:41 2023 +0100
     2.2 +++ b/src/main/java/cz/frantovo/rozsireneatributy/Konfigurace.java	Sun Dec 24 00:38:41 2023 +0100
     2.3 @@ -17,8 +17,11 @@
     2.4  package cz.frantovo.rozsireneatributy;
     2.5  
     2.6  import java.io.File;
     2.7 +import java.util.Arrays;
     2.8 +import java.util.HashSet;
     2.9  import java.util.LinkedList;
    2.10  import java.util.List;
    2.11 +import java.util.Set;
    2.12  
    2.13  /**
    2.14   * @author Ing. František Kučera (frantovo.cz)
    2.15 @@ -89,9 +92,32 @@
    2.16  		}
    2.17  	}
    2.18  
    2.19 +	public enum RežimZamykání {
    2.20 +		VYPNUTÉ("vypnuté", "disabled"),
    2.21 +		VOLITELNÉ("volitelné", "optional"),
    2.22 +		POVINNÉ("povinné", "mandatory");
    2.23 +
    2.24 +		private final Set<String> hodnoty = new HashSet<>();
    2.25 +
    2.26 +		private RežimZamykání(String... hodnoty) {
    2.27 +			this.hodnoty.addAll(Arrays.asList(hodnoty));
    2.28 +		}
    2.29 +
    2.30 +		public boolean odpovídá(String hodnota) {
    2.31 +			return hodnoty.contains(hodnota);
    2.32 +		}
    2.33 +
    2.34 +		public static RežimZamykání najdiRežim(String hodnota) {
    2.35 +			for (RežimZamykání režim : values()) {
    2.36 +				if (režim.odpovídá(hodnota)) return režim;
    2.37 +			}
    2.38 +			return null;
    2.39 +		}
    2.40 +	}
    2.41 +
    2.42  	private File soubor;
    2.43  
    2.44 -	private boolean povinnéZamykání = false;
    2.45 +	private RežimZamykání režimZamykání = RežimZamykání.VOLITELNÉ;
    2.46  
    2.47  	private final List<DefiniceAtributu> atributy = new LinkedList<>();
    2.48  
    2.49 @@ -103,12 +129,12 @@
    2.50  		this.soubor = soubor;
    2.51  	}
    2.52  
    2.53 -	public boolean isPovinnéZamykání() {
    2.54 -		return povinnéZamykání;
    2.55 +	public RežimZamykání getRežimZamykání() {
    2.56 +		return režimZamykání;
    2.57  	}
    2.58  
    2.59 -	public void setPovinnéZamykání(boolean povinnéZamykání) {
    2.60 -		this.povinnéZamykání = povinnéZamykání;
    2.61 +	public void setRežimZamykání(RežimZamykání režimZamykání) {
    2.62 +		this.režimZamykání = režimZamykání;
    2.63  	}
    2.64  
    2.65  	public List<DefiniceAtributu> getAtributy() {
     3.1 --- a/src/main/java/cz/frantovo/rozsireneatributy/gui/Panel.java	Tue Dec 19 00:47:41 2023 +0100
     3.2 +++ b/src/main/java/cz/frantovo/rozsireneatributy/gui/Panel.java	Sun Dec 24 00:38:41 2023 +0100
     3.3 @@ -18,6 +18,7 @@
     3.4  
     3.5  import cz.frantovo.rozsireneatributy.Atribut;
     3.6  import cz.frantovo.rozsireneatributy.CSV;
     3.7 +import cz.frantovo.rozsireneatributy.Konfigurace;
     3.8  import java.awt.Toolkit;
     3.9  import java.awt.datatransfer.StringSelection;
    3.10  import java.awt.event.KeyEvent;
    3.11 @@ -32,6 +33,7 @@
    3.12  import javax.swing.ListSelectionModel;
    3.13  import javax.swing.event.ListSelectionEvent;
    3.14  import javax.swing.event.ListSelectionListener;
    3.15 +import javax.swing.table.TableCellEditor;
    3.16  
    3.17  /**
    3.18   * @author Ing. František Kučera (frantovo.cz)
    3.19 @@ -71,19 +73,50 @@
    3.20  			@Override
    3.21  			public void valueChanged(ListSelectionEvent e) {
    3.22  				int řádek = tabulka.getSelectedRow();
    3.23 -				if (řádek < 0) {
    3.24 -					vybranýAtribut = null;
    3.25 -					tlačítkoSmazat.setEnabled(false);
    3.26 -				} else {
    3.27 -					vybranýAtribut = getModel().getAtribut(řádek);
    3.28 -					tlačítkoSmazat.setEnabled(true);
    3.29 -				}
    3.30 +				if (řádek < 0) vybranýAtribut = null;
    3.31 +				else vybranýAtribut = getModel().getAtribut(řádek);
    3.32 +				aktualizujPovolenéÚpravy();
    3.33  			}
    3.34  		});
    3.35  
    3.36  		// Buňky tabulky editovatelné po stisku mezerníku:
    3.37  		tabulka.getInputMap()
    3.38  			.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "startEditing");
    3.39 +
    3.40 +		aktualizujPovolenéÚpravy();
    3.41 +
    3.42 +		// TODO: Provádět IO operace v jiném vlákně
    3.43 +		// SwingWorker.doInBackground() + SwingUtilities.invokeLater()
    3.44 +	}
    3.45 +
    3.46 +	private void aktualizujPovolenéÚpravy() {
    3.47 +		Konfigurace k = model.getKonfigurace();
    3.48 +		switch (k.getRežimZamykání()) {
    3.49 +			case VYPNUTÉ:
    3.50 +				tlačítkoZamknout.setVisible(false);
    3.51 +				setPovolenéÚpravy(true);
    3.52 +				break;
    3.53 +			case VOLITELNÉ:
    3.54 +				setPovolenéÚpravy(true);
    3.55 +				break;
    3.56 +			case POVINNÉ:
    3.57 +				setPovolenéÚpravy(tlačítkoZamknout.isSelected());
    3.58 +				break;
    3.59 +			default:
    3.60 +				break;
    3.61 +		}
    3.62 +	}
    3.63 +
    3.64 +	private void setPovolenéÚpravy(boolean povolené) {
    3.65 +		if (!povolené) {
    3.66 +			TableCellEditor ce = tabulka.getCellEditor();
    3.67 +			if (ce != null) ce.cancelCellEditing();
    3.68 +			tabulka.clearSelection();
    3.69 +		}
    3.70 +
    3.71 +		tabulka.setEnabled(povolené);
    3.72 +		tlačítkoPřidat.setEnabled(povolené);
    3.73 +		tlačítkoSmazat.setEnabled(povolené && tabulka.getSelectedRow() > -1);
    3.74  	}
    3.75  
    3.76  	private void nastavEditor() {
    3.77 @@ -109,7 +142,7 @@
    3.78  			překlady.getString("chyba.titulek"), JOptionPane.ERROR_MESSAGE);
    3.79  		log.log(Level.WARNING, hláška, chyba);
    3.80  	}
    3.81 -	
    3.82 +
    3.83  	private void kopírujDoSchránky() {
    3.84  		try {
    3.85  			StringWriter výstup = new StringWriter();
    3.86 @@ -243,6 +276,7 @@
    3.87  
    3.88      private void tlačítkoZamknoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tlačítkoZamknoutActionPerformed
    3.89  		try {
    3.90 +			aktualizujPovolenéÚpravy();
    3.91  			model.nastavZámek(tlačítkoZamknout.isSelected());
    3.92  		} catch (Exception e) {
    3.93  			zobrazChybovouHlášku(překlady
     4.1 --- a/src/main/resources/cz/frantovo/rozsireneatributy/Překlady_cs.properties	Tue Dec 19 00:47:41 2023 +0100
     4.2 +++ b/src/main/resources/cz/frantovo/rozsireneatributy/Překlady_cs.properties	Sun Dec 24 00:38:41 2023 +0100
     4.3 @@ -21,5 +21,5 @@
     4.4  p\u0159idatAtribut=P\u0159idat atribut
     4.5  smazatAtribut=Smazat atribut
     4.6  znovuNa\u010d\u00edst=Znovu na\u010d\u00edst
     4.7 -zamknout=Zamknout
     4.8 +zamknout=Zamknout a upravovat
     4.9  zamknout.popis=Otev\u0159e soubor pro z\u00e1pis a vytvo\u0159\u00ed na n\u011bm z\u00e1mek. P\u0159i odemknut\u00ed uvoln\u00ed z\u00e1mek a zav\u0159e soubor.
     5.1 --- a/src/main/resources/cz/frantovo/rozsireneatributy/Překlady_en.properties	Tue Dec 19 00:47:41 2023 +0100
     5.2 +++ b/src/main/resources/cz/frantovo/rozsireneatributy/Překlady_en.properties	Sun Dec 24 00:38:41 2023 +0100
     5.3 @@ -21,5 +21,5 @@
     5.4  p\u0159idatAtribut=Add attribute
     5.5  smazatAtribut=Delete attribute
     5.6  znovuNa\u010d\u00edst=Reload all
     5.7 -zamknout=Lock
     5.8 +zamknout=Lock & editing
     5.9  zamknout.popis=Open the file for write and lock it. On unlocking, release the lock and close the file.