wörk wörk (day 4)
* added checkbox JList for preset mod list * added multiselect of JList without pressing CTRL * added compareable for Mod object * added user modsets * added functions to add/save/remove/clone Modset to user config * added fast check (only detect byte size changes) * added load user modsets * added "focusing" correct button corresponding to the tab * added JComboBox to select a preset in updater * changed button alignment * fixed synclist for single ModFile #coronatime
This commit is contained in:
parent
5eeffde3c3
commit
112bc228d4
5
pom.xml
5
pom.xml
@ -46,6 +46,11 @@
|
|||||||
<artifactId>zsyncer</artifactId>
|
<artifactId>zsyncer</artifactId>
|
||||||
<version>1de0d3f651</version>
|
<version>1de0d3f651</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jgoodies</groupId>
|
||||||
|
<artifactId>jgoodies-forms</artifactId>
|
||||||
|
<version>1.9.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -42,10 +42,14 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<alignmentY value="0.0"/>
|
<alignmentY value="0.0"/>
|
||||||
<borderPainted value="true"/>
|
<borderPainted value="true"/>
|
||||||
|
<focusCycleRoot value="false"/>
|
||||||
<focusPainted value="false"/>
|
<focusPainted value="false"/>
|
||||||
<focusable value="true"/>
|
<focusable value="false"/>
|
||||||
<font size="16"/>
|
<font size="16"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<icon value="icons/settings_16.png"/>
|
<icon value="icons/settings_16.png"/>
|
||||||
|
<iconTextGap value="10"/>
|
||||||
|
<inheritsPopupMenu value="true"/>
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<text resource-bundle="lang" key="settings"/>
|
<text resource-bundle="lang" key="settings"/>
|
||||||
</properties>
|
</properties>
|
||||||
@ -64,8 +68,11 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<focusPainted value="false"/>
|
<focusPainted value="false"/>
|
||||||
|
<focusable value="false"/>
|
||||||
<font size="16"/>
|
<font size="16"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<icon value="icons/download_16.png"/>
|
<icon value="icons/download_16.png"/>
|
||||||
|
<iconTextGap value="10"/>
|
||||||
<text resource-bundle="lang" key="update"/>
|
<text resource-bundle="lang" key="update"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
@ -75,8 +82,11 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<focusPainted value="false"/>
|
<focusPainted value="false"/>
|
||||||
|
<focusable value="false"/>
|
||||||
<font size="16"/>
|
<font size="16"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<icon value="icons/play_16.png"/>
|
<icon value="icons/play_16.png"/>
|
||||||
|
<iconTextGap value="10"/>
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<text resource-bundle="lang" key="play"/>
|
<text resource-bundle="lang" key="play"/>
|
||||||
</properties>
|
</properties>
|
||||||
@ -168,8 +178,11 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<focusPainted value="false"/>
|
<focusPainted value="false"/>
|
||||||
|
<focusable value="false"/>
|
||||||
<font size="16"/>
|
<font size="16"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<icon value="icons/preset_16.png"/>
|
<icon value="icons/preset_16.png"/>
|
||||||
|
<iconTextGap value="10"/>
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<text resource-bundle="lang" key="presets"/>
|
<text resource-bundle="lang" key="presets"/>
|
||||||
</properties>
|
</properties>
|
||||||
@ -180,8 +193,11 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<focusPainted value="false"/>
|
<focusPainted value="false"/>
|
||||||
|
<focusable value="false"/>
|
||||||
<font size="16"/>
|
<font size="16"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<icon value="icons/changelog_16.png"/>
|
<icon value="icons/changelog_16.png"/>
|
||||||
|
<iconTextGap value="10"/>
|
||||||
<text resource-bundle="lang" key="changelog"/>
|
<text resource-bundle="lang" key="changelog"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
@ -445,20 +461,24 @@
|
|||||||
<text resource-bundle="lang" key="abort"/>
|
<text resource-bundle="lang" key="abort"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="d7e4b" class="javax.swing.JButton" binding="syncCheckButton">
|
<component id="d7e4b" class="javax.swing.JButton" binding="syncIntensiveCheckButton">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<enabled value="false"/>
|
<enabled value="false"/>
|
||||||
<text resource-bundle="lang" key="check"/>
|
<text resource-bundle="lang" key="intensive_check"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<hspacer id="a2208">
|
<component id="df55f" class="javax.swing.JButton" binding="syncFastCheckButton">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</hspacer>
|
<properties>
|
||||||
|
<enabled value="false"/>
|
||||||
|
<text resource-bundle="lang" key="fast_check"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<component id="c97ef" class="javax.swing.JLabel">
|
<component id="c97ef" class="javax.swing.JLabel">
|
||||||
@ -561,23 +581,25 @@
|
|||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<grid id="b8ac" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="b8ac" layout-manager="FormLayout">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<colspec value="fill:d:grow"/>
|
||||||
|
<colspec value="left:4dlu:noGrow"/>
|
||||||
|
<colspec value="fill:d:grow"/>
|
||||||
<constraints border-constraint="Center"/>
|
<constraints border-constraint="Center"/>
|
||||||
<properties/>
|
<properties/>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<component id="e74aa" class="javax.swing.JLabel">
|
|
||||||
<constraints>
|
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<text resource-bundle="lang" key="total_file_size"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<component id="f5997" class="javax.swing.JLabel">
|
<component id="f5997" class="javax.swing.JLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text resource-bundle="lang" key="speed"/>
|
<text resource-bundle="lang" key="speed"/>
|
||||||
@ -585,31 +607,17 @@
|
|||||||
</component>
|
</component>
|
||||||
<component id="25551" class="javax.swing.JLabel">
|
<component id="25551" class="javax.swing.JLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text resource-bundle="lang" key="remaining_time"/>
|
<text resource-bundle="lang" key="remaining_time"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="b28b6" class="javax.swing.JLabel" binding="syncSizeLabel">
|
<component id="9148" class="javax.swing.JLabel" binding="syncFileCountLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
<forms/>
|
||||||
<properties>
|
|
||||||
<text value="0.0 B"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<component id="617c7" class="javax.swing.JLabel" binding="syncDownloadSpeedLabel">
|
|
||||||
<constraints>
|
|
||||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<text value=""/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<component id="b64ac" class="javax.swing.JLabel">
|
|
||||||
<constraints>
|
|
||||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text value=""/>
|
<text value=""/>
|
||||||
@ -617,15 +625,44 @@
|
|||||||
</component>
|
</component>
|
||||||
<component id="28be3" class="javax.swing.JLabel">
|
<component id="28be3" class="javax.swing.JLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text resource-bundle="lang" key="file_count"/>
|
<text resource-bundle="lang" key="file_count"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="9148" class="javax.swing.JLabel" binding="syncFileCountLabel">
|
<component id="e74aa" class="javax.swing.JLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text resource-bundle="lang" key="total_file_size"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="b28b6" class="javax.swing.JLabel" binding="syncSizeLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text value="0.0 B/0.0 B"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="617c7" class="javax.swing.JLabel" binding="syncDownloadSpeedLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text value=""/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="63dca" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<text value=""/>
|
<text value=""/>
|
||||||
@ -793,7 +830,7 @@
|
|||||||
<text resource-bundle="lang" key="expand_all"/>
|
<text resource-bundle="lang" key="expand_all"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="43543" class="javax.swing.JComboBox" binding="comboBox1" default-binding="true">
|
<component id="43543" class="javax.swing.JComboBox" binding="syncPresetCombo">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@ -945,10 +982,78 @@
|
|||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<verticalScrollBarPolicy value="22"/>
|
<horizontalScrollBarPolicy value="31"/>
|
||||||
|
<verticalScrollBarPolicy value="20"/>
|
||||||
|
</properties>
|
||||||
|
<border type="empty"/>
|
||||||
|
<children>
|
||||||
|
<grid id="87071" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="100" left="70" bottom="100" right="70"/>
|
||||||
|
<constraints/>
|
||||||
|
<properties/>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<grid id="1679e" binding="presetNotePane" layout-manager="FormLayout">
|
||||||
|
<rowspec value="center:d:noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<colspec value="fill:d:grow"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<visible value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children/>
|
<children>
|
||||||
|
<component id="7b832" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font size="14" style="1"/>
|
||||||
|
<text resource-bundle="lang" key="note"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="d466d" class="javax.swing.JButton" binding="presetNoteButton">
|
||||||
|
<constraints>
|
||||||
|
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text resource-bundle="lang" key="clone_preset"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<grid id="8f1ff" binding="presetNotePaneWrapper" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties/>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="862fc" class="javax.swing.JTextPane" binding="presetNoteTextPane">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<preferred-size width="200" height="50"/>
|
||||||
|
</grid>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<enabled value="true"/>
|
||||||
|
<text resource-bundle="lang" key="presets_note"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</children>
|
||||||
</scrollpane>
|
</scrollpane>
|
||||||
<component id="3960a" class="javax.swing.JLabel">
|
<component id="3960a" class="javax.swing.JLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
@ -1033,7 +1138,9 @@
|
|||||||
<preferred-size width="150" height="50"/>
|
<preferred-size width="150" height="50"/>
|
||||||
</grid>
|
</grid>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties>
|
||||||
|
<selectionMode value="1"/>
|
||||||
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="4fbf3" class="javax.swing.JList" binding="modList">
|
<component id="4fbf3" class="javax.swing.JList" binding="modList">
|
||||||
<constraints>
|
<constraints>
|
||||||
|
@ -3,10 +3,12 @@ package de.mc8051.arma3launcher;
|
|||||||
import de.mc8051.arma3launcher.interfaces.Observer;
|
import de.mc8051.arma3launcher.interfaces.Observer;
|
||||||
import de.mc8051.arma3launcher.model.JCheckBoxTree;
|
import de.mc8051.arma3launcher.model.JCheckBoxTree;
|
||||||
import de.mc8051.arma3launcher.model.ModListRenderer;
|
import de.mc8051.arma3launcher.model.ModListRenderer;
|
||||||
|
import de.mc8051.arma3launcher.model.MultiSelectModel;
|
||||||
import de.mc8051.arma3launcher.model.PresetListRenderer;
|
import de.mc8051.arma3launcher.model.PresetListRenderer;
|
||||||
import de.mc8051.arma3launcher.model.PresetTableModel;
|
import de.mc8051.arma3launcher.model.PresetTableModel;
|
||||||
import de.mc8051.arma3launcher.model.RepositoryTreeNode;
|
import de.mc8051.arma3launcher.model.RepositoryTreeNode;
|
||||||
import de.mc8051.arma3launcher.model.ServerTableModel;
|
import de.mc8051.arma3launcher.model.ServerTableModel;
|
||||||
|
import de.mc8051.arma3launcher.model.TabbedPaneUI;
|
||||||
import de.mc8051.arma3launcher.objects.AbstractMod;
|
import de.mc8051.arma3launcher.objects.AbstractMod;
|
||||||
import de.mc8051.arma3launcher.objects.Changelog;
|
import de.mc8051.arma3launcher.objects.Changelog;
|
||||||
import de.mc8051.arma3launcher.objects.Mod;
|
import de.mc8051.arma3launcher.objects.Mod;
|
||||||
@ -24,10 +26,12 @@ import de.mc8051.arma3launcher.utils.Humanize;
|
|||||||
import de.mc8051.arma3launcher.utils.ImageUtils;
|
import de.mc8051.arma3launcher.utils.ImageUtils;
|
||||||
import de.mc8051.arma3launcher.utils.LangUtils;
|
import de.mc8051.arma3launcher.utils.LangUtils;
|
||||||
import de.mc8051.arma3launcher.utils.TaskBarUtils;
|
import de.mc8051.arma3launcher.utils.TaskBarUtils;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.text.DefaultFormatter;
|
import javax.swing.text.DefaultFormatter;
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
import javax.swing.tree.DefaultTreeModel;
|
import javax.swing.tree.DefaultTreeModel;
|
||||||
@ -37,12 +41,12 @@ import java.awt.*;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ItemEvent;
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.awt.event.ItemListener;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -51,11 +55,12 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,13 +130,13 @@ public class LauncherGUI implements Observer {
|
|||||||
private JButton expandAllButton;
|
private JButton expandAllButton;
|
||||||
private JProgressBar syncCheckProgress;
|
private JProgressBar syncCheckProgress;
|
||||||
private JButton syncCheckAbortButton;
|
private JButton syncCheckAbortButton;
|
||||||
private JButton syncCheckButton;
|
private JButton syncIntensiveCheckButton;
|
||||||
public JProgressBar syncDownloadProgress;
|
public JProgressBar syncDownloadProgress;
|
||||||
public JProgressBar syncFileProgress;
|
public JProgressBar syncFileProgress;
|
||||||
private JButton syncDownloadButton;
|
private JButton syncDownloadButton;
|
||||||
private JButton syncDownloadAbortButton;
|
private JButton syncDownloadAbortButton;
|
||||||
private JButton syncPauseButton;
|
private JButton syncPauseButton;
|
||||||
private JComboBox comboBox1;
|
private JComboBox syncPresetCombo;
|
||||||
private JButton refreshRepoButton;
|
private JButton refreshRepoButton;
|
||||||
private JPanel updateTreePanel;
|
private JPanel updateTreePanel;
|
||||||
private JScrollPane updateTreeScrolPane;
|
private JScrollPane updateTreeScrolPane;
|
||||||
@ -161,6 +166,11 @@ public class LauncherGUI implements Observer {
|
|||||||
private JLabel aboutProjectLabel;
|
private JLabel aboutProjectLabel;
|
||||||
private JLabel aboutDeveloperLabel;
|
private JLabel aboutDeveloperLabel;
|
||||||
private JLabel aboutCopyrightLabel;
|
private JLabel aboutCopyrightLabel;
|
||||||
|
private JButton syncFastCheckButton;
|
||||||
|
private JButton presetNoteButton;
|
||||||
|
private JTextPane presetNoteTextPane;
|
||||||
|
private JPanel presetNotePaneWrapper;
|
||||||
|
private JPanel presetNotePane;
|
||||||
|
|
||||||
private JCheckBoxTree repoTree;
|
private JCheckBoxTree repoTree;
|
||||||
private FileChecker fileChecker;
|
private FileChecker fileChecker;
|
||||||
@ -186,7 +196,9 @@ public class LauncherGUI implements Observer {
|
|||||||
RepositoryManger.getInstance().refreshModset();
|
RepositoryManger.getInstance().refreshModset();
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
updateTreePanel.remove(tree1);
|
switchTab(Tab.PLAY);
|
||||||
|
|
||||||
|
updateTreePanel.removeAll();
|
||||||
|
|
||||||
repoTree = new JCheckBoxTree();
|
repoTree = new JCheckBoxTree();
|
||||||
updateTreePanel.add(repoTree, BorderLayout.CENTER);
|
updateTreePanel.add(repoTree, BorderLayout.CENTER);
|
||||||
@ -197,25 +209,9 @@ public class LauncherGUI implements Observer {
|
|||||||
updateTreePanel.revalidate();
|
updateTreePanel.revalidate();
|
||||||
updateTreePanel.repaint();
|
updateTreePanel.repaint();
|
||||||
|
|
||||||
tabbedPane1.setUI(new BasicTabbedPaneUI() {
|
tabbedPane1.setUI(new TabbedPaneUI());
|
||||||
private final Insets borderInsets = new Insets(0, 0, 0, 0);
|
|
||||||
|
|
||||||
@Override
|
Insets x = new Insets(5, 15, 5, 0);
|
||||||
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Insets getContentBorderInsets(int tabPlacement) {
|
|
||||||
return borderInsets;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Insets x = new Insets(5, 5, 5, 5);
|
|
||||||
settingsPanelButton.setMargin(x);
|
settingsPanelButton.setMargin(x);
|
||||||
updatePanelButton.setMargin(x);
|
updatePanelButton.setMargin(x);
|
||||||
playPanelButton.setMargin(x);
|
playPanelButton.setMargin(x);
|
||||||
@ -228,7 +224,9 @@ public class LauncherGUI implements Observer {
|
|||||||
presetList.setModel(new PresetTableModel());
|
presetList.setModel(new PresetTableModel());
|
||||||
|
|
||||||
presetList.setCellRenderer(new PresetListRenderer());
|
presetList.setCellRenderer(new PresetListRenderer());
|
||||||
modList.setCellRenderer(new ModListRenderer());
|
modList.setCellRenderer(new ModListRenderer<String>());
|
||||||
|
|
||||||
|
modList.setSelectionModel(new MultiSelectModel());
|
||||||
|
|
||||||
subtitle.setText(
|
subtitle.setText(
|
||||||
ArmA3Launcher.config.getString("subtitle")
|
ArmA3Launcher.config.getString("subtitle")
|
||||||
@ -248,20 +246,26 @@ public class LauncherGUI implements Observer {
|
|||||||
aboutClient.setText(ArmA3Launcher.config.getString("name") + " v" + ArmA3Launcher.VERSION);
|
aboutClient.setText(ArmA3Launcher.config.getString("name") + " v" + ArmA3Launcher.VERSION);
|
||||||
|
|
||||||
aboutDeveloperLabel.setText("<html><a href=''>https://gurkengewuerz.de</a></html>");
|
aboutDeveloperLabel.setText("<html><a href=''>https://gurkengewuerz.de</a></html>");
|
||||||
aboutProjectLabel.setText("<html><a href=''>"+ArmA3Launcher.config.getString("social.github")+"</a></html>");
|
aboutProjectLabel.setText("<html><a href=''>" + ArmA3Launcher.config.getString("social.github") + "</a></html>");
|
||||||
|
|
||||||
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("disclaimer.html");
|
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("disclaimer.html");
|
||||||
if(resourceAsStream != null) {
|
if (resourceAsStream != null) {
|
||||||
Scanner s = new Scanner(resourceAsStream).useDelimiter("\\A");
|
Scanner s = new Scanner(resourceAsStream).useDelimiter("\\A");
|
||||||
String result = s.hasNext() ? s.next() : "";
|
String result = s.hasNext() ? s.next() : "";
|
||||||
disclaimer.setText(result);
|
disclaimer.setText(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
presetNoteTextPane.setHighlighter(null);
|
||||||
|
presetNoteTextPane.getCaret().setVisible(false);
|
||||||
|
presetNoteTextPane.setBackground(presetNotePaneWrapper.getBackground());
|
||||||
|
presetNoteTextPane.setCaretColor(presetNoteTextPane.getBackground());
|
||||||
|
|
||||||
|
presetNoteTextPane.setPreferredSize(new Dimension(-1, -1));
|
||||||
|
|
||||||
aboutCopyrightLabel.setText(aboutCopyrightLabel.getText().replace("{year}", "" + Calendar.getInstance().get(Calendar.YEAR)));
|
aboutCopyrightLabel.setText(aboutCopyrightLabel.getText().replace("{year}", "" + Calendar.getInstance().get(Calendar.YEAR)));
|
||||||
|
|
||||||
twitterIcon.setBorder(new EmptyBorder(2,2,2,2));
|
twitterIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||||
githubIcon.setBorder(new EmptyBorder(2,2,2,2));
|
githubIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||||
|
|
||||||
settingScrollPane.getVerticalScrollBar().setUnitIncrement(16);
|
settingScrollPane.getVerticalScrollBar().setUnitIncrement(16);
|
||||||
updateTreeScrolPane.getVerticalScrollBar().setUnitIncrement(16);
|
updateTreeScrolPane.getVerticalScrollBar().setUnitIncrement(16);
|
||||||
@ -270,16 +274,17 @@ public class LauncherGUI implements Observer {
|
|||||||
presetList.addListSelectionListener(e -> {
|
presetList.addListSelectionListener(e -> {
|
||||||
if (!e.getValueIsAdjusting()) {
|
if (!e.getValueIsAdjusting()) {
|
||||||
PresetTableModel m = (PresetTableModel) presetList.getModel();
|
PresetTableModel m = (PresetTableModel) presetList.getModel();
|
||||||
Modset modset = (Modset) m.getElementAt(presetList.getSelectedIndex());
|
Object elementAt = m.getElementAt(presetList.getSelectedIndex());
|
||||||
|
Modset modset = (Modset) elementAt;
|
||||||
|
|
||||||
if (modset.getType() == Modset.Type.SERVER) {
|
if (modset.getType() == Modset.Type.SERVER || modset.getType() == Modset.Type.PLACEHOLDER) {
|
||||||
renamePresetButton.setEnabled(false);
|
renamePresetButton.setEnabled(false);
|
||||||
removePresetButtom.setEnabled(false);
|
removePresetButtom.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
renamePresetButton.setEnabled(true);
|
renamePresetButton.setEnabled(true);
|
||||||
removePresetButtom.setEnabled(true);
|
removePresetButtom.setEnabled(true);
|
||||||
}
|
}
|
||||||
clonePresetButton.setEnabled(true);
|
clonePresetButton.setEnabled(modset.getType() != Modset.Type.PLACEHOLDER);
|
||||||
|
|
||||||
updateModList(modset);
|
updateModList(modset);
|
||||||
}
|
}
|
||||||
@ -300,14 +305,11 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
|
|
||||||
collapseAllButton.addActionListener(e -> repoTree.collapseAllNodes());
|
collapseAllButton.addActionListener(e -> repoTree.collapseAllNodes());
|
||||||
playPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(0));
|
playPanelButton.addActionListener(e -> switchTab(Tab.PLAY));
|
||||||
updatePanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(1));
|
updatePanelButton.addActionListener(e -> switchTab(Tab.UPDATE));
|
||||||
changelogButton.addActionListener(e -> {
|
changelogButton.addActionListener(e -> switchTab(Tab.CHANGELOG));
|
||||||
tabbedPane1.setSelectedIndex(2);
|
presetPanelButton.addActionListener(e -> switchTab(Tab.PRESET));
|
||||||
Changelog.refresh();
|
settingsPanelButton.addActionListener(e -> switchTab(Tab.SETTING));
|
||||||
});
|
|
||||||
presetPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(3));
|
|
||||||
settingsPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(4));
|
|
||||||
|
|
||||||
refreshRepoButton.addActionListener(e -> RepositoryManger.getInstance().refreshModset());
|
refreshRepoButton.addActionListener(e -> RepositoryManger.getInstance().refreshModset());
|
||||||
expandAllButton.addActionListener(e -> repoTree.expandAllNodes());
|
expandAllButton.addActionListener(e -> repoTree.expandAllNodes());
|
||||||
@ -315,24 +317,17 @@ public class LauncherGUI implements Observer {
|
|||||||
syncCheckAbortButton.addActionListener(e -> fileChecker.stop());
|
syncCheckAbortButton.addActionListener(e -> fileChecker.stop());
|
||||||
|
|
||||||
|
|
||||||
syncCheckButton.addActionListener(e -> {
|
syncIntensiveCheckButton.addActionListener(e -> fileCheck(false));
|
||||||
syncCheckButton.setEnabled(false);
|
syncFastCheckButton.addActionListener(e -> fileCheck(true));
|
||||||
syncCheckAbortButton.setEnabled(true);
|
|
||||||
syncCheckStatusLabel.setText("Running!");
|
|
||||||
new Thread(() -> fileChecker.check()).start();
|
|
||||||
|
|
||||||
refreshRepoButton.setEnabled(false);
|
|
||||||
|
|
||||||
repoTree.setCheckboxesEnabled(false);
|
|
||||||
repoTree.setCheckboxesChecked(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
syncDownloadButton.addActionListener(e -> {
|
syncDownloadButton.addActionListener(e -> {
|
||||||
if (!fileChecker.isChecked()) return;
|
if (!fileChecker.isChecked()) return;
|
||||||
|
if (lastSynclist == null) return;
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
syncDownloadAbortButton.setEnabled(true);
|
syncDownloadAbortButton.setEnabled(true);
|
||||||
syncPauseButton.setEnabled(true);
|
syncPauseButton.setEnabled(true);
|
||||||
syncCheckButton.setEnabled(false);
|
syncIntensiveCheckButton.setEnabled(false);
|
||||||
|
syncFastCheckButton.setEnabled(false);
|
||||||
refreshRepoButton.setEnabled(false);
|
refreshRepoButton.setEnabled(false);
|
||||||
new Thread(() -> syncer.sync(lastSynclist.clone())).start();
|
new Thread(() -> syncer.sync(lastSynclist.clone())).start();
|
||||||
});
|
});
|
||||||
@ -350,7 +345,7 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent e) {
|
public void mouseExited(MouseEvent e) {
|
||||||
twitterIcon.setBorder(new EmptyBorder(2,2,2,2));
|
twitterIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -362,14 +357,14 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseExited(MouseEvent e) {
|
public void mouseExited(MouseEvent e) {
|
||||||
githubIcon.setBorder(new EmptyBorder(2,2,2,2));
|
githubIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
aboutLabel.addMouseListener(new MouseAdapter() {
|
aboutLabel.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
tabbedPane1.setSelectedIndex(5);
|
switchTab(Tab.ABOUT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -400,6 +395,125 @@ public class LauncherGUI implements Observer {
|
|||||||
openURL(ArmA3Launcher.config.getString("social.github"));
|
openURL(ArmA3Launcher.config.getString("social.github"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modList.addListSelectionListener(new ListSelectionListener() {
|
||||||
|
@Override
|
||||||
|
public void valueChanged(ListSelectionEvent e) {
|
||||||
|
if (presetList.getSelectedIndex() == -1) return;
|
||||||
|
JList<?> list = (JList<?>) e.getSource();
|
||||||
|
ListModel<?> model = list.getModel();
|
||||||
|
|
||||||
|
ListSelectionModel listSelectionModel = list.getSelectionModel();
|
||||||
|
|
||||||
|
int minSelectionIndex = listSelectionModel.getMinSelectionIndex();
|
||||||
|
int maxSelectionIndex = listSelectionModel.getMaxSelectionIndex();
|
||||||
|
|
||||||
|
List<String> selectedMods = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = minSelectionIndex; i <= maxSelectionIndex; i++) {
|
||||||
|
if (listSelectionModel.isSelectedIndex(i)) {
|
||||||
|
selectedMods.add(String.valueOf(model.getElementAt(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||||
|
if (presetList.getSelectedIndex() == -1) return;
|
||||||
|
Object elementAt = model1.getElementAt(presetList.getSelectedIndex());
|
||||||
|
Modset selectedModset = (Modset) elementAt;
|
||||||
|
if (selectedModset.getType() == Modset.Type.PLACEHOLDER) return;
|
||||||
|
selectedModset.getMods().clear();
|
||||||
|
selectedModset.setMods(selectedMods);
|
||||||
|
updateModsetList();
|
||||||
|
selectedModset.save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newPresetButtom.addActionListener(e -> {
|
||||||
|
String modname = JOptionPane.showInputDialog(null, "", LangUtils.getInstance().getString("new_modset_name"));
|
||||||
|
if (modname.isEmpty()) return;
|
||||||
|
if (Modset.MODSET_LIST.containsKey(modname)) {
|
||||||
|
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Modset ms = new Modset(modname, new JSONArray(), Modset.Type.CLIENT);
|
||||||
|
updateModsetList();
|
||||||
|
ms.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
presetNoteButton.addActionListener(e -> clonePresetButton.doClick());
|
||||||
|
clonePresetButton.addActionListener(e -> {
|
||||||
|
if (presetList.getSelectedIndex() == -1) return;
|
||||||
|
String newName = JOptionPane.showInputDialog(null, "", LangUtils.getInstance().getString("new_modset_name"));
|
||||||
|
if (newName.isEmpty()) return;
|
||||||
|
if (Modset.MODSET_LIST.containsKey(newName)) {
|
||||||
|
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||||
|
Modset selectedModset = ((Modset) model1.getElementAt(presetList.getSelectedIndex()));
|
||||||
|
Modset newModset = selectedModset.clone(newName, Modset.Type.CLIENT);
|
||||||
|
updateModsetList();
|
||||||
|
newModset.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
removePresetButtom.addActionListener(e -> {
|
||||||
|
if (presetList.getSelectedIndex() == -1) return;
|
||||||
|
modList.setModel(new DefaultListModel<>());
|
||||||
|
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||||
|
((Modset) model1.getElementAt(presetList.getSelectedIndex())).removeFromConfig();
|
||||||
|
updateModsetList();
|
||||||
|
});
|
||||||
|
|
||||||
|
renamePresetButton.addActionListener(e -> {
|
||||||
|
if (presetList.getSelectedIndex() == -1) return;
|
||||||
|
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||||
|
Modset selectedModset = ((Modset) model1.getElementAt(presetList.getSelectedIndex()));
|
||||||
|
|
||||||
|
Object newNameO = JOptionPane.showInputDialog(null, "",
|
||||||
|
LangUtils.getInstance().getString("new_modset_name"), JOptionPane.QUESTION_MESSAGE, null, null, selectedModset.getName());
|
||||||
|
if(newNameO == null) return;
|
||||||
|
String newName = (String) newNameO;
|
||||||
|
if (newName.isEmpty()) return;
|
||||||
|
if (Modset.MODSET_LIST.containsKey(newName)) {
|
||||||
|
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Modset newModset = selectedModset.clone(newName, Modset.Type.CLIENT);
|
||||||
|
updateModsetList();
|
||||||
|
selectedModset.removeFromConfig();
|
||||||
|
newModset.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
syncPresetCombo.addItemListener(new ItemListener() {
|
||||||
|
@Override
|
||||||
|
public void itemStateChanged(ItemEvent e) {
|
||||||
|
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||||
|
DefaultComboBoxModel<Modset> model = (DefaultComboBoxModel<Modset>) syncPresetCombo.getModel();
|
||||||
|
Modset elementAt = model.getElementAt(((JComboBox) e.getItemSelectable()).getSelectedIndex());
|
||||||
|
repoTree.setCheckboxesChecked(false);
|
||||||
|
if(elementAt.getType() == Modset.Type.PLACEHOLDER) return;
|
||||||
|
|
||||||
|
List<String> collect = elementAt.getMods().stream().map(Mod::getName).collect(Collectors.toList());
|
||||||
|
|
||||||
|
DefaultTreeModel repoModel = (DefaultTreeModel) repoTree.getModel();
|
||||||
|
RepositoryTreeNode root = (RepositoryTreeNode) repoModel.getRoot();
|
||||||
|
|
||||||
|
for (int i = 0; i < root.getChildCount(); i++) {
|
||||||
|
TreeNode childAt = root.getChildAt(i);
|
||||||
|
if(!collect.contains(childAt.toString())) continue;
|
||||||
|
final TreePath treePath = new TreePath(new TreeNode[]{root, childAt});
|
||||||
|
repoTree.checkSubTree(treePath, true);
|
||||||
|
repoTree.updatePredecessorsWithCheckMode(treePath, true);
|
||||||
|
}
|
||||||
|
repoTree.revalidate();
|
||||||
|
repoTree.repaint();
|
||||||
|
updateDownloadLabel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void infoBox(String infoMessage, String titleBar) {
|
public static void infoBox(String infoMessage, String titleBar) {
|
||||||
@ -438,13 +552,15 @@ public class LauncherGUI implements Observer {
|
|||||||
if (SteamTimer.arma_running) {
|
if (SteamTimer.arma_running) {
|
||||||
playButton.setEnabled(false);
|
playButton.setEnabled(false);
|
||||||
playPresetButton.setEnabled(false);
|
playPresetButton.setEnabled(false);
|
||||||
syncCheckButton.setEnabled(false);
|
syncIntensiveCheckButton.setEnabled(false);
|
||||||
|
syncFastCheckButton.setEnabled(false);
|
||||||
refreshRepoButton.setEnabled(false);
|
refreshRepoButton.setEnabled(false);
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
|
|
||||||
playButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
playButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||||
playPresetButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
playPresetButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||||
syncCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
syncIntensiveCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||||
|
syncFastCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||||
} else {
|
} else {
|
||||||
if (SteamTimer.steam_running) {
|
if (SteamTimer.steam_running) {
|
||||||
if (pathSet) {
|
if (pathSet) {
|
||||||
@ -469,20 +585,23 @@ public class LauncherGUI implements Observer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pathSet) {
|
if (pathSet) {
|
||||||
syncCheckButton.setEnabled(true);
|
syncIntensiveCheckButton.setEnabled(true);
|
||||||
|
syncFastCheckButton.setEnabled(true);
|
||||||
refreshRepoButton.setEnabled(true);
|
refreshRepoButton.setEnabled(true);
|
||||||
|
|
||||||
syncDownloadButton.setEnabled(fileChecker.isChecked());
|
syncDownloadButton.setEnabled(fileChecker.isChecked());
|
||||||
|
|
||||||
syncCheckButton.setToolTipText(null);
|
syncIntensiveCheckButton.setToolTipText(null);
|
||||||
refreshRepoButton.setToolTipText(null);
|
refreshRepoButton.setToolTipText(null);
|
||||||
} else {
|
} else {
|
||||||
syncCheckButton.setEnabled(false);
|
syncIntensiveCheckButton.setEnabled(false);
|
||||||
|
syncFastCheckButton.setEnabled(false);
|
||||||
refreshRepoButton.setEnabled(false);
|
refreshRepoButton.setEnabled(false);
|
||||||
|
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
|
|
||||||
syncCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
syncIntensiveCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||||
|
syncFastCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||||
refreshRepoButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
refreshRepoButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +783,7 @@ public class LauncherGUI implements Observer {
|
|||||||
if (!isSelected) continue;
|
if (!isSelected) continue;
|
||||||
|
|
||||||
ArrayList<String> treePathList = new ArrayList<>();
|
ArrayList<String> treePathList = new ArrayList<>();
|
||||||
for (int i = 2; i < path.length; i++) {
|
for (int i = (path.length > 2 ? 2 : 1); i < path.length; i++) {
|
||||||
treePathList.add(String.valueOf(((DefaultMutableTreeNode) path[i]).getUserObject()));
|
treePathList.add(String.valueOf(((DefaultMutableTreeNode) path[i]).getUserObject()));
|
||||||
}
|
}
|
||||||
String treePath = String.join("/", treePathList);
|
String treePath = String.join("/", treePathList);
|
||||||
@ -693,14 +812,33 @@ public class LauncherGUI implements Observer {
|
|||||||
return synclist;
|
return synclist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateModList(Modset modset) {
|
public void updateModList(final Modset modset) {
|
||||||
ListModel<String> model = (ListModel) modList.getModel();
|
if (modset == null) return;
|
||||||
// TODO: Show All Mods (keyname)
|
DefaultListModel<String> listModel = new DefaultListModel<>();
|
||||||
// Show not installed Mods with red font
|
|
||||||
// Select Mod if in modset.Mods
|
if (modset.getType() == Modset.Type.PLACEHOLDER) return;
|
||||||
// Custom Checkbox Render
|
int[] select = new int[modset.getMods().size()];
|
||||||
// Wenn modset.type == Server alle Checkboxen deaktivieren!
|
|
||||||
// Show hint that server modsets cant be edited
|
AtomicInteger selectCounter = new AtomicInteger(0);
|
||||||
|
RepositoryManger.MOD_LIST.stream()
|
||||||
|
.filter((am) -> am instanceof Mod)
|
||||||
|
.sorted()
|
||||||
|
.forEach((abstractMod) -> {
|
||||||
|
final int i = listModel.getSize();
|
||||||
|
listModel.add(i, abstractMod.getName());
|
||||||
|
for (Mod mod : modset.getMods()) {
|
||||||
|
if (mod.getName().equals(abstractMod.getName())) {
|
||||||
|
select[selectCounter.getAndIncrement()] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
modList.setModel(listModel);
|
||||||
|
modList.setSelectedIndices(select);
|
||||||
|
modList.setEnabled(modset.getType() != Modset.Type.SERVER);
|
||||||
|
presetNotePane.setVisible(modset.getType() == Modset.Type.SERVER);
|
||||||
|
modList.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateRepoTree() {
|
public void updateRepoTree() {
|
||||||
@ -769,6 +907,17 @@ public class LauncherGUI implements Observer {
|
|||||||
repoTree.addCheckChangeEventListener(new JCheckBoxTree.CheckChangeEventListener() {
|
repoTree.addCheckChangeEventListener(new JCheckBoxTree.CheckChangeEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void checkStateChanged(JCheckBoxTree.CheckChangeEvent event) {
|
public void checkStateChanged(JCheckBoxTree.CheckChangeEvent event) {
|
||||||
|
syncPresetCombo.setSelectedIndex(0);
|
||||||
|
|
||||||
|
updateDownloadLabel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expandAllButton.setEnabled(true);
|
||||||
|
collapseAllButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDownloadLabel() {
|
||||||
lastSynclist = getSyncList();
|
lastSynclist = getSyncList();
|
||||||
if (lastSynclist.getSize() != 0)
|
if (lastSynclist.getSize() != 0)
|
||||||
syncSizeLabel.setText("0.0 B/" + Humanize.binaryPrefix(lastSynclist.getSize()));
|
syncSizeLabel.setText("0.0 B/" + Humanize.binaryPrefix(lastSynclist.getSize()));
|
||||||
@ -781,11 +930,6 @@ public class LauncherGUI implements Observer {
|
|||||||
syncFileCountLabel.setText("");
|
syncFileCountLabel.setText("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
expandAllButton.setEnabled(true);
|
|
||||||
collapseAllButton.setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getNodeColor(String mod, ModFile mf) {
|
public Color getNodeColor(String mod, ModFile mf) {
|
||||||
if (fileChecker.getAdded().containsKey(mod)) {
|
if (fileChecker.getAdded().containsKey(mod)) {
|
||||||
@ -863,7 +1007,7 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(String s) {
|
public void update(String s) {
|
||||||
System.out.println(s);
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "Observer received: " + s);
|
||||||
if (s.equals(RepositoryManger.Type.METADATA.toString())) {
|
if (s.equals(RepositoryManger.Type.METADATA.toString())) {
|
||||||
switch (RepositoryManger.getInstance().getStatus(RepositoryManger.Type.METADATA)) {
|
switch (RepositoryManger.getInstance().getStatus(RepositoryManger.Type.METADATA)) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
@ -878,16 +1022,7 @@ public class LauncherGUI implements Observer {
|
|||||||
Server.SERVER_LIST.forEach((name, server) -> model.add(server));
|
Server.SERVER_LIST.forEach((name, server) -> model.add(server));
|
||||||
});
|
});
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
updateModsetList();
|
||||||
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
|
||||||
model.clear();
|
|
||||||
|
|
||||||
model.add(new Modset("--Server", Modset.Type.CLIENT, null, false));
|
|
||||||
|
|
||||||
Modset.MODSET_LIST.forEach((name, set) -> {
|
|
||||||
model.add(set);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (s.equals("steamtimer")) {
|
} else if (s.equals("steamtimer")) {
|
||||||
@ -918,7 +1053,8 @@ public class LauncherGUI implements Observer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (s.equals("fileChecker")) {
|
} else if (s.equals("fileChecker")) {
|
||||||
syncCheckButton.setEnabled(true);
|
syncIntensiveCheckButton.setEnabled(true);
|
||||||
|
syncFastCheckButton.setEnabled(true);
|
||||||
syncCheckAbortButton.setEnabled(false);
|
syncCheckAbortButton.setEnabled(false);
|
||||||
syncCheckStatusLabel.setText("Finished!");
|
syncCheckStatusLabel.setText("Finished!");
|
||||||
updateRepoTree();
|
updateRepoTree();
|
||||||
@ -933,9 +1069,14 @@ public class LauncherGUI implements Observer {
|
|||||||
syncDownloadButton.setEnabled(true);
|
syncDownloadButton.setEnabled(true);
|
||||||
syncPauseButton.setEnabled(false);
|
syncPauseButton.setEnabled(false);
|
||||||
|
|
||||||
|
refreshRepoButton.setEnabled(true);
|
||||||
|
|
||||||
syncChangedFileSizeLabel.setText(Humanize.binaryPrefix(fileChecker.getSize()));
|
syncChangedFileSizeLabel.setText(Humanize.binaryPrefix(fileChecker.getSize()));
|
||||||
|
|
||||||
|
lastSynclist = null;
|
||||||
} else if (s.equals("fileCheckerStopped")) {
|
} else if (s.equals("fileCheckerStopped")) {
|
||||||
syncCheckButton.setEnabled(true);
|
syncIntensiveCheckButton.setEnabled(true);
|
||||||
|
syncFastCheckButton.setEnabled(true);
|
||||||
syncCheckAbortButton.setEnabled(false);
|
syncCheckAbortButton.setEnabled(false);
|
||||||
syncCheckProgress.setValue(0);
|
syncCheckProgress.setValue(0);
|
||||||
syncCheckStatusLabel.setText("Failed!");
|
syncCheckStatusLabel.setText("Failed!");
|
||||||
@ -954,8 +1095,9 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
syncChangedFileSizeLabel.setText("0.0 B");
|
syncChangedFileSizeLabel.setText("0.0 B");
|
||||||
|
|
||||||
|
lastSynclist = null;
|
||||||
} else if (s.equals("syncStopped")) {
|
} else if (s.equals("syncStopped")) {
|
||||||
new Thread(() -> fileChecker.check()).start();
|
new Thread(() -> fileChecker.check(true)).start();
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
syncDownloadAbortButton.setEnabled(false);
|
syncDownloadAbortButton.setEnabled(false);
|
||||||
@ -967,7 +1109,7 @@ public class LauncherGUI implements Observer {
|
|||||||
TaskBarUtils.getInstance().off();
|
TaskBarUtils.getInstance().off();
|
||||||
});
|
});
|
||||||
} else if (s.equals("syncComplete")) {
|
} else if (s.equals("syncComplete")) {
|
||||||
new Thread(() -> fileChecker.check()).start();
|
new Thread(() -> fileChecker.check(true)).start();
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
syncDownloadAbortButton.setEnabled(false);
|
syncDownloadAbortButton.setEnabled(false);
|
||||||
@ -1001,6 +1143,41 @@ public class LauncherGUI implements Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateModsetList() {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
if (((DefaultComboBoxModel<Modset>)syncPresetCombo.getModel()).getSize() > 0){
|
||||||
|
syncPresetCombo.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
||||||
|
model.clear();
|
||||||
|
|
||||||
|
model.add(new Modset("--Server", Modset.Type.PLACEHOLDER, null, false));
|
||||||
|
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() == Modset.Type.SERVER).sorted().forEach(model::add);
|
||||||
|
|
||||||
|
model.add(new Modset("--User", Modset.Type.PLACEHOLDER, null, false));
|
||||||
|
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() == Modset.Type.CLIENT).sorted().forEach(model::add);
|
||||||
|
|
||||||
|
DefaultComboBoxModel<Modset> presetModel = new DefaultComboBoxModel<>();
|
||||||
|
presetModel.addElement(new Modset("", Modset.Type.PLACEHOLDER, null, false));
|
||||||
|
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() != Modset.Type.PLACEHOLDER).sorted().forEach(presetModel::addElement);
|
||||||
|
|
||||||
|
syncPresetCombo.setModel(presetModel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fileCheck(boolean fastscan) {
|
||||||
|
syncIntensiveCheckButton.setEnabled(false);
|
||||||
|
syncFastCheckButton.setEnabled(false);
|
||||||
|
syncCheckAbortButton.setEnabled(true);
|
||||||
|
syncCheckStatusLabel.setText("Running!");
|
||||||
|
new Thread(() -> fileChecker.check(fastscan)).start();
|
||||||
|
|
||||||
|
refreshRepoButton.setEnabled(false);
|
||||||
|
|
||||||
|
repoTree.setCheckboxesEnabled(false);
|
||||||
|
repoTree.setCheckboxesChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
public void exit() {
|
public void exit() {
|
||||||
fileChecker.stop();
|
fileChecker.stop();
|
||||||
syncer.stop();
|
syncer.stop();
|
||||||
@ -1012,4 +1189,59 @@ public class LauncherGUI implements Observer {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void switchTab(Tab tab) {
|
||||||
|
Color focusBackgroundColor = UIManager.getColor("Button.default.focusColor");
|
||||||
|
Color backgroundColor = UIManager.getColor("Button.background");
|
||||||
|
|
||||||
|
playPanelButton.setBackground(backgroundColor);
|
||||||
|
updatePanelButton.setBackground(backgroundColor);
|
||||||
|
changelogButton.setBackground(backgroundColor);
|
||||||
|
presetPanelButton.setBackground(backgroundColor);
|
||||||
|
settingsPanelButton.setBackground(backgroundColor);
|
||||||
|
|
||||||
|
switch (tab) {
|
||||||
|
case PLAY:
|
||||||
|
playPanelButton.setBackground(focusBackgroundColor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UPDATE:
|
||||||
|
updatePanelButton.setBackground(focusBackgroundColor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHANGELOG:
|
||||||
|
changelogButton.setBackground(focusBackgroundColor);
|
||||||
|
Changelog.refresh();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PRESET:
|
||||||
|
presetPanelButton.setBackground(focusBackgroundColor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETTING:
|
||||||
|
settingsPanelButton.setBackground(focusBackgroundColor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabbedPane1.setSelectedIndex(tab.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Tab {
|
||||||
|
PLAY(0),
|
||||||
|
UPDATE(1),
|
||||||
|
CHANGELOG(2),
|
||||||
|
PRESET(3),
|
||||||
|
SETTING(4),
|
||||||
|
ABOUT(5);
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
Tab(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ public class JCheckBoxTree extends JTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When a node is checked/unchecked, updating the states of the predecessors
|
// When a node is checked/unchecked, updating the states of the predecessors
|
||||||
protected void updatePredecessorsWithCheckMode(TreePath tp, boolean check) {
|
public void updatePredecessorsWithCheckMode(TreePath tp, boolean check) {
|
||||||
TreePath parentPath = tp.getParentPath();
|
TreePath parentPath = tp.getParentPath();
|
||||||
// If it is the root, stop the recursive calls and return
|
// If it is the root, stop the recursive calls and return
|
||||||
if (parentPath == null) {
|
if (parentPath == null) {
|
||||||
@ -266,7 +266,7 @@ public class JCheckBoxTree extends JTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recursively checks/unchecks a subtree
|
// Recursively checks/unchecks a subtree
|
||||||
protected void checkSubTree(TreePath tp, boolean check) {
|
public void checkSubTree(TreePath tp, boolean check) {
|
||||||
CheckedNode cn = nodesCheckingState.get(tp);
|
CheckedNode cn = nodesCheckingState.get(tp);
|
||||||
cn.isSelected = check;
|
cn.isSelected = check;
|
||||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
|
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
|
||||||
|
@ -4,22 +4,28 @@ import javax.swing.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by gurkengewuerz.de on 25.03.2020.
|
* Created by gurkengewuerz.de on 28.03.2020.
|
||||||
*/
|
*/
|
||||||
public class ModListRenderer extends JCheckBox implements ListCellRenderer {
|
public class ModListRenderer<E> extends JCheckBox implements
|
||||||
|
ListCellRenderer<E> {
|
||||||
|
|
||||||
public Component getListCellRendererComponent(JList list, Object value, int index,
|
private static final long serialVersionUID = 3734536442230283966L;
|
||||||
boolean isSelected, boolean cellHasFocus) {
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getListCellRendererComponent(JList<? extends E> list,
|
||||||
|
E value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||||
setComponentOrientation(list.getComponentOrientation());
|
setComponentOrientation(list.getComponentOrientation());
|
||||||
|
|
||||||
setFont(list.getFont());
|
setFont(list.getFont());
|
||||||
|
setText(String.valueOf(value));
|
||||||
|
|
||||||
setBackground(list.getBackground());
|
setBackground(list.getBackground());
|
||||||
setForeground(list.getForeground());
|
setForeground(list.getForeground());
|
||||||
|
|
||||||
setSelected(isSelected);
|
setSelected(isSelected);
|
||||||
setEnabled(list.isEnabled());
|
setEnabled(list.isEnabled());
|
||||||
|
|
||||||
setText(value == null ? "" : value.toString());
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package de.mc8051.arma3launcher.model;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by gurkengewuerz.de on 28.03.2020.
|
||||||
|
*/
|
||||||
|
public class MultiSelectModel extends DefaultListSelectionModel {
|
||||||
|
|
||||||
|
private int i0 = -1;
|
||||||
|
private int i1 = -1;
|
||||||
|
|
||||||
|
public void setSelectionInterval(int index0, int index1) {
|
||||||
|
if (i0 == index0 && i1 == index1) {
|
||||||
|
if (getValueIsAdjusting()) {
|
||||||
|
setValueIsAdjusting(false);
|
||||||
|
setSelection(index0, index1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i0 = index0;
|
||||||
|
i1 = index1;
|
||||||
|
setValueIsAdjusting(false);
|
||||||
|
setSelection(index0, index1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSelection(int index0, int index1) {
|
||||||
|
if (super.isSelectedIndex(index0)) {
|
||||||
|
super.removeSelectionInterval(index0, index1);
|
||||||
|
} else {
|
||||||
|
super.addSelectionInterval(index0, index1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package de.mc8051.arma3launcher.model;
|
||||||
|
|
||||||
|
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by gurkengewuerz.de on 28.03.2020.
|
||||||
|
*/
|
||||||
|
public class TabbedPaneUI extends BasicTabbedPaneUI {
|
||||||
|
|
||||||
|
private final Insets borderInsets = new Insets(0, 0, 0, 0);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Insets getContentBorderInsets(int tabPlacement) {
|
||||||
|
return borderInsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
|||||||
/**
|
/**
|
||||||
* Created by gurkengewuerz.de on 25.03.2020.
|
* Created by gurkengewuerz.de on 25.03.2020.
|
||||||
*/
|
*/
|
||||||
public class Mod implements AbstractMod {
|
public class Mod implements AbstractMod, Comparable {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private long size;
|
private long size;
|
||||||
@ -37,4 +37,9 @@ public class Mod implements AbstractMod {
|
|||||||
public Mod clone() {
|
public Mod clone() {
|
||||||
return new Mod(name, size, new ArrayList<>(files));
|
return new Mod(name, size, new ArrayList<>(files));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
return getName().compareToIgnoreCase(((Mod) o).getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
package de.mc8051.arma3launcher.objects;
|
package de.mc8051.arma3launcher.objects;
|
||||||
|
|
||||||
|
import de.mc8051.arma3launcher.ArmA3Launcher;
|
||||||
|
import org.ini4j.Ini;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by gurkengewuerz.de on 25.03.2020.
|
* Created by gurkengewuerz.de on 25.03.2020.
|
||||||
*/
|
*/
|
||||||
public class Modset {
|
public class Modset implements Comparable {
|
||||||
|
|
||||||
public static HashMap<String, Modset> MODSET_LIST = new HashMap<>();
|
public static HashMap<String, Modset> MODSET_LIST = new HashMap<>();
|
||||||
|
|
||||||
@ -27,23 +33,69 @@ public class Modset {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
this.mods = mods;
|
this.mods = mods;
|
||||||
|
|
||||||
if(add) MODSET_LIST.put(name, this);
|
if (add) MODSET_LIST.put(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Modset(JSONObject o, Type type) {
|
public Modset(String name, JSONArray modlist, Type type) {
|
||||||
if(!o.has("name") || !o.has("mods")) return;
|
for (int j = 0; j < modlist.length(); j++) {
|
||||||
name = o.getString("name");
|
|
||||||
|
|
||||||
JSONArray modlist = o.getJSONArray("mods");
|
|
||||||
for(int j = 0; j < modlist.length(); j++){
|
|
||||||
mods.add(new Mod(modlist.getString(j)));
|
mods.add(new Mod(modlist.getString(j)));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
MODSET_LIST.put(name, this);
|
MODSET_LIST.put(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Modset(JSONObject o, Type type) {
|
||||||
|
this(o.getString("name"), o.getJSONArray("mods"), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
if (type != Type.CLIENT) return;
|
||||||
|
|
||||||
|
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||||
|
if (section == null) {
|
||||||
|
section = ArmA3Launcher.user_config.add("presets");
|
||||||
|
}
|
||||||
|
if (section != null) {
|
||||||
|
|
||||||
|
List<String> list = mods.stream()
|
||||||
|
.map(Mod::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
JSONArray ja = new JSONArray(list);
|
||||||
|
if (section.containsKey(name))
|
||||||
|
section.replace(name, ja.toString());
|
||||||
|
else
|
||||||
|
section.add(name, ja.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArmA3Launcher.user_config.store();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeFromConfig() {
|
||||||
|
MODSET_LIST.remove(name);
|
||||||
|
if (type != Type.CLIENT) return;
|
||||||
|
|
||||||
|
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||||
|
if (section != null) {
|
||||||
|
if (section.containsKey(name)) {
|
||||||
|
section.remove(name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArmA3Launcher.user_config.store();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -60,8 +112,31 @@ public class Modset {
|
|||||||
// TODO: Implement play with this Modset
|
// TODO: Implement play with this Modset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Modset clone(String newName, Type newType) {
|
||||||
|
return new Modset(newName, newType, new ArrayList<>(mods));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Modset clone() {
|
||||||
|
return new Modset(name, type, mods, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMods(List<String> selectedMods) {
|
||||||
|
mods.addAll(selectedMods.stream().map(Mod::new).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
return getName().compareToIgnoreCase(((Modset) o).getName());
|
||||||
|
}
|
||||||
|
|
||||||
public static enum Type {
|
public static enum Type {
|
||||||
SERVER,
|
SERVER,
|
||||||
CLIENT
|
CLIENT,
|
||||||
|
PLACEHOLDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,7 @@ import de.mc8051.arma3launcher.objects.Mod;
|
|||||||
import de.mc8051.arma3launcher.objects.ModFile;
|
import de.mc8051.arma3launcher.objects.ModFile;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -45,6 +43,10 @@ public class FileChecker implements Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void check() {
|
public void check() {
|
||||||
|
check(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void check(boolean fastscan) {
|
||||||
deleted.clear();
|
deleted.clear();
|
||||||
changed.clear();
|
changed.clear();
|
||||||
changedCount = 0;
|
changedCount = 0;
|
||||||
@ -59,16 +61,16 @@ public class FileChecker implements Observable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
||||||
if(stop) {
|
if (stop) {
|
||||||
stop = false;
|
stop = false;
|
||||||
notifyObservers("fileCheckerStopped");
|
notifyObservers("fileCheckerStopped");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(abstractMod instanceof Mod) {
|
if (abstractMod instanceof Mod) {
|
||||||
Mod m = (Mod) abstractMod;
|
Mod m = (Mod) abstractMod;
|
||||||
|
|
||||||
for (ModFile mf : m.getFiles()) {
|
for (ModFile mf : m.getFiles()) {
|
||||||
checkFile(m.getName(), mf);
|
checkFile(m.getName(), mf, fastscan);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
@ -76,7 +78,7 @@ public class FileChecker implements Observable {
|
|||||||
pb.setValue(finalI);
|
pb.setValue(finalI);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(stop) {
|
if (stop) {
|
||||||
stop = false;
|
stop = false;
|
||||||
notifyObservers("fileCheckerStopped");
|
notifyObservers("fileCheckerStopped");
|
||||||
return;
|
return;
|
||||||
@ -84,7 +86,7 @@ public class FileChecker implements Observable {
|
|||||||
}
|
}
|
||||||
} else if (abstractMod instanceof ModFile) {
|
} else if (abstractMod instanceof ModFile) {
|
||||||
ModFile mf = (ModFile) abstractMod;
|
ModFile mf = (ModFile) abstractMod;
|
||||||
checkFile(mf.getName(), mf);
|
checkFile(mf.getName(), mf, fastscan);
|
||||||
i++;
|
i++;
|
||||||
int finalI1 = i;
|
int finalI1 = i;
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
@ -106,11 +108,11 @@ public class FileChecker implements Observable {
|
|||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFile(String mod, ModFile mf) {
|
private void checkFile(String mod, ModFile mf, boolean fastscan) {
|
||||||
ArrayList<ModFile> temp = new ArrayList<>();
|
ArrayList<ModFile> temp = new ArrayList<>();
|
||||||
|
|
||||||
if(!mf.exists()) {
|
if (!mf.exists()) {
|
||||||
if(added.containsKey(mod)) temp =added.get(mod);
|
if (added.containsKey(mod)) temp = added.get(mod);
|
||||||
temp.add(mf);
|
temp.add(mf);
|
||||||
added.put(mod, temp);
|
added.put(mod, temp);
|
||||||
addedCount++;
|
addedCount++;
|
||||||
@ -118,8 +120,10 @@ public class FileChecker implements Observable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mf.getLocalSize() != mf.getSize() || !mf.getSHA1Sum().equalsIgnoreCase(mf.getLocalGeneratedSHA1Sum())) {
|
|
||||||
if(changed.containsKey(mod)) temp =changed.get(mod);
|
if (fastscan || !mf.getSHA1Sum().equalsIgnoreCase(mf.getLocalGeneratedSHA1Sum())) {
|
||||||
|
if (mf.getLocalSize() != mf.getSize()) {
|
||||||
|
if (changed.containsKey(mod)) temp = changed.get(mod);
|
||||||
temp.add(mf);
|
temp.add(mf);
|
||||||
changed.put(mod, temp);
|
changed.put(mod, temp);
|
||||||
changedCount++;
|
changedCount++;
|
||||||
@ -127,10 +131,11 @@ public class FileChecker implements Observable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkDeleted() {
|
private void checkDeleted() {
|
||||||
String modPath = ArmA3Launcher.user_config.get("client", "modPath");
|
String modPath = ArmA3Launcher.user_config.get("client", "modPath");
|
||||||
if(modPath == null) modPath = "";
|
if (modPath == null) modPath = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<Path> filePathList = Files.find(Paths.get(modPath),
|
List<Path> filePathList = Files.find(Paths.get(modPath),
|
||||||
@ -144,7 +149,7 @@ public class FileChecker implements Observable {
|
|||||||
|
|
||||||
outerloop:
|
outerloop:
|
||||||
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
||||||
if(abstractMod instanceof Mod) {
|
if (abstractMod instanceof Mod) {
|
||||||
Mod m = (Mod) abstractMod;
|
Mod m = (Mod) abstractMod;
|
||||||
|
|
||||||
for (ModFile mf : m.getFiles()) {
|
for (ModFile mf : m.getFiles()) {
|
||||||
|
@ -10,6 +10,7 @@ import de.mc8051.arma3launcher.objects.ModFile;
|
|||||||
import de.mc8051.arma3launcher.objects.Modset;
|
import de.mc8051.arma3launcher.objects.Modset;
|
||||||
import de.mc8051.arma3launcher.objects.Server;
|
import de.mc8051.arma3launcher.objects.Server;
|
||||||
import de.mc8051.arma3launcher.utils.Callback;
|
import de.mc8051.arma3launcher.utils.Callback;
|
||||||
|
import org.ini4j.Ini;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||||
|
|
||||||
@ -93,10 +95,19 @@ public class RepositoryManger implements Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Modset.MODSET_LIST.clear();
|
||||||
|
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||||
|
if (section != null) {
|
||||||
|
for (String key : section.keySet()) {
|
||||||
|
String jsonString = section.get(key);
|
||||||
|
JSONArray ja = new JSONArray(jsonString);
|
||||||
|
new Modset(key, ja, Modset.Type.CLIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JSONObject jsonObject = new JSONObject(r.getBody());
|
JSONObject jsonObject = new JSONObject(r.getBody());
|
||||||
|
|
||||||
if (jsonObject.has("modsets")) {
|
if (jsonObject.has("modsets")) {
|
||||||
Modset.MODSET_LIST.clear();
|
|
||||||
JSONArray modsets = jsonObject.getJSONArray("modsets");
|
JSONArray modsets = jsonObject.getJSONArray("modsets");
|
||||||
if (modsets.length() > 0) {
|
if (modsets.length() > 0) {
|
||||||
for (int i = 0; i < modsets.length(); i++) {
|
for (int i = 0; i < modsets.length(); i++) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TheTown Client",
|
"name": "TheTown Client",
|
||||||
"title": "Welcome! :P",
|
"title": "Willkommen!",
|
||||||
"subtitle": "${name} v${version}",
|
"subtitle": "${name} v${version}",
|
||||||
"sync": {
|
"sync": {
|
||||||
"useragent": "TheTownSyncer",
|
"useragent": "TheTownSyncer",
|
||||||
|
@ -29,7 +29,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<h1>Licenses</h1>
|
<h1>Licenses</h1>
|
||||||
<h3>de.mc8051.arma3launcher</h3>
|
<h2>de.mc8051.arma3launcher</h2>
|
||||||
<tt>
|
<tt>
|
||||||
MIT License<br/>
|
MIT License<br/>
|
||||||
<br/>
|
<br/>
|
||||||
@ -54,7 +54,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
SOFTWARE.<br/>
|
SOFTWARE.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>com.formdev.flatlaf</h3>
|
<h2>com.formdev.flatlaf</h2>
|
||||||
<a href="">https://github.com/JFormDesigner/FlatLaf</a><br/>
|
<a href="">https://github.com/JFormDesigner/FlatLaf</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
Copyright 2019 FormDev Software GmbH<br/>
|
Copyright 2019 FormDev Software GmbH<br/>
|
||||||
@ -72,7 +72,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
limitations under the License.<br/>
|
limitations under the License.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>co.bitshfted.xapps.zsync</h3>
|
<h2>co.bitshfted.xapps.zsync</h2>
|
||||||
<a href="">https://github.com/bitshifted/zsyncer</a><br/>
|
<a href="">https://github.com/bitshifted/zsyncer</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
Copyright (c) 2015, Salesforce.com, Inc. All rights reserved.<br/>
|
Copyright (c) 2015, Salesforce.com, Inc. All rights reserved.<br/>
|
||||||
@ -99,7 +99,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br/>
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>com.github.RalleYTN.SimpleRegistry</h3>
|
<h2>com.github.RalleYTN.SimpleRegistry</h2>
|
||||||
<a href="">https://github.com/RalleYTN/SimpleRegistry</a><br/>
|
<a href="">https://github.com/RalleYTN/SimpleRegistry</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
MIT License<br/>
|
MIT License<br/>
|
||||||
@ -125,7 +125,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
SOFTWARE.<br/>
|
SOFTWARE.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>com.typesafe.config</h3>
|
<h2>com.typesafe.config</h2>
|
||||||
<a href="">https://github.com/lightbend/config</a><br/>
|
<a href="">https://github.com/lightbend/config</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
Copyright (C) 2011-2012 Typesafe Inc. http://typesafe.com<br/>
|
Copyright (C) 2011-2012 Typesafe Inc. http://typesafe.com<br/>
|
||||||
@ -143,7 +143,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
limitations under the License.<br/>
|
limitations under the License.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<br/>
|
<br/>
|
||||||
<h3>org.ini4j.ini4j</h3>
|
<h2>org.ini4j.ini4j</h2>
|
||||||
<a href="">https://github.com/facebookarchive/ini4j</a><br/>
|
<a href="">https://github.com/facebookarchive/ini4j</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
Copyright 2005,2009 Ivan SZKIBA<br/>
|
Copyright 2005,2009 Ivan SZKIBA<br/>
|
||||||
@ -160,7 +160,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
See the License for the specific language governing permissions and<br/>
|
See the License for the specific language governing permissions and<br/>
|
||||||
limitations under the License.<br/>
|
limitations under the License.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
<h3>org.json.json</h3>
|
<h2>org.json.json</h2>
|
||||||
<a href="">https://json.org</a><br/>
|
<a href="">https://json.org</a><br/>
|
||||||
<tt>
|
<tt>
|
||||||
Copyright (c) 2018 JSON.org<br/>
|
Copyright (c) 2018 JSON.org<br/>
|
||||||
@ -185,5 +185,35 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
|
||||||
SOFTWARE.<br/>
|
SOFTWARE.<br/>
|
||||||
</tt>
|
</tt>
|
||||||
|
<h2>com.jgoodies.forms</h2>
|
||||||
|
<tt>
|
||||||
|
Copyright (c) 2002-2015 JGoodies Software GmbH. All Rights Reserved.<br/>
|
||||||
|
<br/>
|
||||||
|
Redistribution and use in source and binary forms, with or without<br/>
|
||||||
|
modification, are permitted provided that the following conditions are met:<br/>
|
||||||
|
<br/>
|
||||||
|
o Redistributions of source code must retain the above copyright notice,<br/>
|
||||||
|
this list of conditions and the following disclaimer.<br/>
|
||||||
|
<br/>
|
||||||
|
o Redistributions in binary form must reproduce the above copyright notice,<br/>
|
||||||
|
this list of conditions and the following disclaimer in the documentation<br/>
|
||||||
|
and/or other materials provided with the distribution.<br/>
|
||||||
|
<br/>
|
||||||
|
o Neither the name of JGoodies Software GmbH nor the names of<br/>
|
||||||
|
its contributors may be used to endorse or promote products derived<br/>
|
||||||
|
from this software without specific prior written permission.<br/>
|
||||||
|
<br/>
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br/>
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,<br/>
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR<br/>
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR<br/>
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,<br/>
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,<br/>
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;<br/>
|
||||||
|
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,<br/>
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE<br/>
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,<br/>
|
||||||
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br/>
|
||||||
|
</tt>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -102,3 +102,11 @@ star_on_github="Star us" auf GitHub
|
|||||||
client_up_to_date=Client ist aktuell
|
client_up_to_date=Client ist aktuell
|
||||||
developer_page=Entwickler-Seite
|
developer_page=Entwickler-Seite
|
||||||
project_page=Projektseite
|
project_page=Projektseite
|
||||||
|
fast_check=Schnelle Prüfung
|
||||||
|
intensive_check=Intensive Prüfung
|
||||||
|
note=Hinweis
|
||||||
|
presets_note=Vorlagen können nur als Vorlage für neue User-Vorlagen verwendet werden. Du kannst eine eigene Vorlage auf Bases dieser Server Vorlage erstellen. Dabei wird die Liste aler Mods übernommen.
|
||||||
|
clone_preset=Vorlage klonen
|
||||||
|
new_modset_name=Modsset Name
|
||||||
|
modset_exists_msg=Bitte wähle ein anderen Namen für deine Vorlage.
|
||||||
|
modset_exists=Preset mit diesen Namen existiert bereits
|
@ -100,3 +100,11 @@ star_on_github=Star us on GitHub
|
|||||||
client_up_to_date=Client is up to date
|
client_up_to_date=Client is up to date
|
||||||
developer_page=Developer page
|
developer_page=Developer page
|
||||||
project_page=Project page
|
project_page=Project page
|
||||||
|
new_modset_name=Modsset name
|
||||||
|
intensive_check=Intensive check
|
||||||
|
fast_check=Fast check
|
||||||
|
note=Note
|
||||||
|
presets_note=Presets can only be used as preset for new user presents. You can create your own custom preset based on this server preset. The list of all mods will be used.
|
||||||
|
clone_preset=Clone preset
|
||||||
|
modset_exists_msg=Please choose another name for your preset.
|
||||||
|
modset_exists=Preset with these names already exists
|
Loading…
Reference in New Issue
Block a user