Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
93cb83e33e | |||
9fe6f34ba3 | |||
3f60d618ff |
10
.idea/libraries/com_google_code_gson_gson_2_8_6.xml
generated
Normal file
10
.idea/libraries/com_google_code_gson_gson_2_8_6.xml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="com.google.code.gson:gson:2.8.6" type="repository">
|
||||||
|
<properties maven-id="com.google.code.gson:gson:2.8.6" />
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
@ -12,5 +12,7 @@
|
|||||||
<orderEntry type="library" name="log4j:log4j:1.2.17" level="project" />
|
<orderEntry type="library" name="log4j:log4j:1.2.17" level="project" />
|
||||||
<orderEntry type="library" name="org.postgresql:postgresql:42.2.19" level="project" />
|
<orderEntry type="library" name="org.postgresql:postgresql:42.2.19" level="project" />
|
||||||
<orderEntry type="library" name="iText-4.2.0-com.itextpdf" level="project" />
|
<orderEntry type="library" name="iText-4.2.0-com.itextpdf" level="project" />
|
||||||
|
<orderEntry type="library" name="org.json:json:20180130" level="project" />
|
||||||
|
<orderEntry type="library" name="com.google.code.gson:gson:2.8.6" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -24,5 +24,6 @@ javadoc = https://git.dergeorg.at/dergeorg/tourplaner
|
|||||||
[map]
|
[map]
|
||||||
key =
|
key =
|
||||||
size = 1500,400
|
size = 1500,400
|
||||||
|
sizePdf = 600,400
|
||||||
path = D:\\TourplanerImages\\
|
path = D:\\TourplanerImages\\
|
||||||
file_pre = file:///
|
file_pre = file:///
|
@ -10,24 +10,62 @@ import java.io.IOException;
|
|||||||
public class DirectionMap {
|
public class DirectionMap {
|
||||||
|
|
||||||
private double dauer, strecke;
|
private double dauer, strecke;
|
||||||
private String start, end, tourname, file;
|
private String start, end, tourname, file, filepdf;
|
||||||
private Image map;
|
private Image map, mappdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holt die Map als image und alle Daten zur berechneten Route
|
||||||
|
*
|
||||||
|
* @param start Startpunkt
|
||||||
|
* @param ende Endpunkt
|
||||||
|
* @param tourname Name der Aktuellen Tour
|
||||||
|
* @throws IOException Fehler beim Image der Map
|
||||||
|
*/
|
||||||
public DirectionMap (String start, String ende, String tourname) throws IOException {
|
public DirectionMap (String start, String ende, String tourname) throws IOException {
|
||||||
this.map = getMap(start, ende);
|
this.map = getMap(start, ende, ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "size"));
|
||||||
|
this.mappdf = getMap(start, ende, ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "sizePdf"));
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.end = ende;
|
this.end = ende;
|
||||||
this.tourname = tourname;
|
this.tourname = tourname;
|
||||||
this.file = ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + this.tourname + ".jpg";
|
this.file = ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + this.tourname + ".jpg";
|
||||||
FileHelper.saveImage(this.map, "jpg", new File(file));
|
this.filepdf = ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + this.tourname + "_pdf.jpg";
|
||||||
|
FileHelper.saveImage(this.map, "jpg", new File(this.file));
|
||||||
|
FileHelper.saveImage(this.mappdf, "jpg", new File(this.filepdf));
|
||||||
|
getDirections(start, ende);
|
||||||
FileHelper.openDefault(file);
|
FileHelper.openDefault(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image getMap(String start, String ende) throws IOException {
|
public double getDauer() {
|
||||||
return HttpHelper.httpGetStaticMap(start, ende);
|
return dauer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getStrecke() {
|
||||||
|
return strecke;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloadet die Map von Mapquest
|
||||||
|
* @param start Startpunkt
|
||||||
|
* @param ende Endpunkt
|
||||||
|
* @return Image von der Map
|
||||||
|
* @throws IOException Fehler beim Get der Map
|
||||||
|
*/
|
||||||
|
private Image getMap(String start, String ende, String size) throws IOException {
|
||||||
|
return HttpHelper.httpGetImage("https://www.mapquestapi.com/staticmap/v5/map?start="+start+"&end="+ende+"&size="+size+"&key="+ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getDirections(String start, String ende) throws IOException {
|
||||||
|
String json = HttpHelper.httpGetJsonString("https://www.mapquestapi.com/directions/v2/route?key="+ ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "key")+"&from="+start+"&to="+ende+"&outFormat=json&ambiguities=ignore&routeType=fastest&doReverseGeocode=false&enhancedNarrative=false&avoidTimedConditions=false");
|
||||||
|
this.strecke = JsonHelper.getDoubleFromJson(json, "distance");
|
||||||
|
this.dauer = formatetTimeToMinutes(JsonHelper.getStingFromJson(json, "formattedTime"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private double formatetTimeToMinutes(String formatetTime){
|
||||||
|
double minutes = 0;
|
||||||
|
String[] result = formatetTime.split(":");
|
||||||
|
minutes += Double.parseDouble(result[0]) * 60;
|
||||||
|
minutes += Double.parseDouble(result[1]);
|
||||||
|
minutes += Double.parseDouble(result[2]) / 60;
|
||||||
|
return minutes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class FileHelper {
|
public class FileHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Öffnet ein File mit dem Standart Program
|
||||||
|
* @param f File Path als string
|
||||||
|
*/
|
||||||
public static void openDefault(String f){
|
public static void openDefault(String f){
|
||||||
// A reference to a text file
|
// A reference to a text file
|
||||||
File file = new File(f);
|
File file = new File(f);
|
||||||
@ -26,11 +30,33 @@ public class FileHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichert ein Image
|
||||||
|
* @param img Das zu speichernde Bild
|
||||||
|
* @param type Dateityp z.b. jpg
|
||||||
|
* @param file Wo die datei zu speichern ist
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
public static void saveImage(Image img, String type, File file) throws IOException {
|
public static void saveImage(Image img, String type, File file) throws IOException {
|
||||||
ImageIO.write(ImgHelper.toBufferedImage(img), type, file);
|
ImageIO.write(ImgHelper.toBufferedImage(img), type, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holt ein image von einem File
|
||||||
|
* @param file File mit dem image
|
||||||
|
* @return Das buffered image
|
||||||
|
* @throws IOException Fehler beim öffnen des bildes
|
||||||
|
*/
|
||||||
public static BufferedImage getImage(File file) throws IOException {
|
public static BufferedImage getImage(File file) throws IOException {
|
||||||
return ImageIO.read(file);
|
return ImageIO.read(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht ein File
|
||||||
|
* @param file File das zu löschen ist
|
||||||
|
* @return false bei error
|
||||||
|
*/
|
||||||
|
public static boolean delFile(File file){
|
||||||
|
return file.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,60 @@
|
|||||||
package tourplaner.business;
|
package tourplaner.business;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Http Hilfsfunktionen
|
||||||
|
*/
|
||||||
public class HttpHelper {
|
public class HttpHelper {
|
||||||
|
|
||||||
public static Image httpGetStaticMap(String start, String end) throws IOException {
|
/**
|
||||||
URL url = new URL("https://www.mapquestapi.com/staticmap/v5/map?start="+start+"&end="+end+"&size="+ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "size")+"&key="+ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "key"));
|
* Holt ein Image von gegebener URL
|
||||||
return ImageIO.read(url);
|
* @param url Url als Sting
|
||||||
|
* @return Image von der Url
|
||||||
|
* @throws IOException Fehler beim Bild holen
|
||||||
|
*/
|
||||||
|
public static Image httpGetImage(String url) throws IOException {
|
||||||
|
URL urls = new URL(url);
|
||||||
|
return ImageIO.read(urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String httpGetJsonString(String url) throws IOException {
|
||||||
|
HttpURLConnection con = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
var myurl = new URL(url);
|
||||||
|
con = (HttpURLConnection) myurl.openConnection();
|
||||||
|
|
||||||
|
con.setRequestMethod("GET");
|
||||||
|
|
||||||
|
StringBuilder content;
|
||||||
|
|
||||||
|
try (BufferedReader in = new BufferedReader(
|
||||||
|
new InputStreamReader(con.getInputStream()))) {
|
||||||
|
|
||||||
|
String line;
|
||||||
|
content = new StringBuilder();
|
||||||
|
|
||||||
|
while ((line = in.readLine()) != null) {
|
||||||
|
|
||||||
|
content.append(line);
|
||||||
|
content.append(System.lineSeparator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return content.toString();
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
assert con != null;
|
||||||
|
con.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package tourplaner.business;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image Hilfsfunktionen
|
||||||
|
*/
|
||||||
public class ImgHelper {
|
public class ImgHelper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
20
src/tourplaner/business/JsonHelper.java
Normal file
20
src/tourplaner/business/JsonHelper.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package tourplaner.business;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
public class JsonHelper {
|
||||||
|
|
||||||
|
public static String getStingFromJson(String json, String gets){
|
||||||
|
return getJObj(json).get("route").getAsJsonObject().get(gets).getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getDoubleFromJson(String json, String gets){
|
||||||
|
return getJObj(json).get("route").getAsJsonObject().get(gets).getAsDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonObject getJObj(String json){
|
||||||
|
return new Gson().fromJson(json, JsonObject.class);
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,13 @@
|
|||||||
package tourplaner.business;
|
package tourplaner.business;
|
||||||
|
|
||||||
|
import com.itextpdf.text.*;
|
||||||
|
import com.itextpdf.text.Font;
|
||||||
|
import com.itextpdf.text.Image;
|
||||||
|
import com.sun.scenario.effect.ImageData;
|
||||||
import tourplaner.object.Log;
|
import tourplaner.object.Log;
|
||||||
import tourplaner.object.Tour;
|
import tourplaner.object.Tour;
|
||||||
|
|
||||||
|
|
||||||
import com.itextpdf.text.Anchor;
|
|
||||||
import com.itextpdf.text.BadElementException;
|
|
||||||
import com.itextpdf.text.Chapter;
|
|
||||||
import com.itextpdf.text.Document;
|
|
||||||
import com.itextpdf.text.DocumentException;
|
|
||||||
import com.itextpdf.text.Element;
|
|
||||||
import com.itextpdf.text.Font;
|
|
||||||
import com.itextpdf.text.List;
|
|
||||||
import com.itextpdf.text.ListItem;
|
|
||||||
import com.itextpdf.text.Paragraph;
|
|
||||||
import com.itextpdf.text.Phrase;
|
|
||||||
import com.itextpdf.text.Section;
|
|
||||||
import com.itextpdf.text.pdf.PdfPCell;
|
import com.itextpdf.text.pdf.PdfPCell;
|
||||||
import com.itextpdf.text.pdf.PdfPTable;
|
import com.itextpdf.text.pdf.PdfPTable;
|
||||||
import com.itextpdf.text.pdf.PdfWriter;
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
@ -28,6 +20,9 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://github.com/ymasory/iText-4.2.0
|
||||||
|
*/
|
||||||
public class Reporter {
|
public class Reporter {
|
||||||
|
|
||||||
private static Font catFont = new Font(Font.TIMES_ROMAN, 18,
|
private static Font catFont = new Font(Font.TIMES_ROMAN, 18,
|
||||||
@ -82,15 +77,24 @@ public class Reporter {
|
|||||||
subCatPart.add(new Paragraph("Zielpunkt der Tour: " + tour.getZiel()));
|
subCatPart.add(new Paragraph("Zielpunkt der Tour: " + tour.getZiel()));
|
||||||
subCatPart.add(new Paragraph("Berechnete Dauer der Tour: " + tour.getDauer()));
|
subCatPart.add(new Paragraph("Berechnete Dauer der Tour: " + tour.getDauer()));
|
||||||
subCatPart.add(new Paragraph("Berechnete Strecke der Tour: " + tour.getStrecke()));
|
subCatPart.add(new Paragraph("Berechnete Strecke der Tour: " + tour.getStrecke()));
|
||||||
|
Paragraph emptyLine = new Paragraph();
|
||||||
|
addEmptyLine(emptyLine, 5);
|
||||||
|
subCatPart.add(emptyLine);
|
||||||
|
|
||||||
|
|
||||||
// now add all this to the document
|
// now add all this to the document
|
||||||
document.add(catPart);
|
document.add(catPart);
|
||||||
|
|
||||||
|
Image image1 = null;
|
||||||
|
try {
|
||||||
|
image1 = Image.getInstance(TourPlaner.getImagePdfPath(tour.getName()));
|
||||||
|
image1.setAlignment(Element.ALIGN_CENTER);
|
||||||
|
image1.scaleAbsolute(600, 400);
|
||||||
|
|
||||||
|
document.add(image1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
ArrayList<Log> logs = tour.getLogs();
|
ArrayList<Log> logs = tour.getLogs();
|
||||||
// Second parameter is the number of the chapter
|
// Second parameter is the number of the chapter
|
||||||
anchor = new Anchor("Logs", catFont);
|
anchor = new Anchor("Logs", catFont);
|
||||||
|
@ -37,11 +37,18 @@ public class TourPlaner{
|
|||||||
* @param tour Neuer Tourname
|
* @param tour Neuer Tourname
|
||||||
* @return false bei error
|
* @return false bei error
|
||||||
*/
|
*/
|
||||||
public static boolean editTour(String oldname, Tour tour){
|
public static boolean editTour(String oldname, Tour tour) throws IOException {
|
||||||
|
FileHelper.delFile(new File(getImagePath(oldname)));
|
||||||
|
FileHelper.delFile(new File(getImagePdfPath(oldname)));
|
||||||
|
DirectionMap directionMap = new DirectionMap(tour.getStart(), tour.getZiel(), tour.getName());
|
||||||
|
tour.setDauer(directionMap.getDauer()+"");
|
||||||
|
tour.setStrecke(directionMap.getStrecke());
|
||||||
return new DbConnect().editTour(oldname, tour);
|
return new DbConnect().editTour(oldname, tour);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean delTour(String tourname){
|
public static boolean delTour(String tourname){
|
||||||
|
FileHelper.delFile(new File(getImagePath(tourname)));
|
||||||
|
FileHelper.delFile(new File(getImagePdfPath(tourname)));
|
||||||
return new DbConnect().delTour(tourname);
|
return new DbConnect().delTour(tourname);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -51,6 +58,8 @@ public class TourPlaner{
|
|||||||
*/
|
*/
|
||||||
public static boolean addTour(Tour newTour) throws IOException {
|
public static boolean addTour(Tour newTour) throws IOException {
|
||||||
DirectionMap directionMap = new DirectionMap(newTour.getStart(), newTour.getZiel(), newTour.getName());
|
DirectionMap directionMap = new DirectionMap(newTour.getStart(), newTour.getZiel(), newTour.getName());
|
||||||
|
newTour.setDauer(directionMap.getDauer()+"");
|
||||||
|
newTour.setStrecke(directionMap.getStrecke());
|
||||||
return new DbConnect().addTour(newTour);
|
return new DbConnect().addTour(newTour);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +70,9 @@ public class TourPlaner{
|
|||||||
public static String getImagePath(String tourname){
|
public static String getImagePath(String tourname){
|
||||||
return ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + tourname + ".jpg";
|
return ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + tourname + ".jpg";
|
||||||
}
|
}
|
||||||
|
public static String getImagePdfPath(String tourname){
|
||||||
|
return ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "map", "path") + tourname + "_pdf.jpg";
|
||||||
|
}
|
||||||
|
|
||||||
public static void openImage(String tourname){
|
public static void openImage(String tourname){
|
||||||
FileHelper.openDefault(getImagePath(tourname));
|
FileHelper.openDefault(getImagePath(tourname));
|
||||||
|
@ -115,7 +115,7 @@
|
|||||||
<tabs>
|
<tabs>
|
||||||
<Tab fx:id="kartenTab" text="Karte">
|
<Tab fx:id="kartenTab" text="Karte">
|
||||||
<AnchorPane>
|
<AnchorPane>
|
||||||
<ImageView fx:id="mapImageView" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="80.0" AnchorPane.leftAnchor="13.0" AnchorPane.rightAnchor="825.0" AnchorPane.topAnchor="0.0" />
|
<ImageView fx:id="mapImageView" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab fx:id="beschreibungTab" text="Beschreibung">
|
<Tab fx:id="beschreibungTab" text="Beschreibung">
|
||||||
|
@ -51,7 +51,11 @@ public class TourplanerController implements Initializable {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void editTourBtn(){
|
private void editTourBtn(){
|
||||||
|
try {
|
||||||
this.viewModel.editTour();
|
this.viewModel.editTour();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
syncTour(this.viewModel.getSelectedTour().getName());
|
syncTour(this.viewModel.getSelectedTour().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +94,7 @@ public class TourplanerController implements Initializable {
|
|||||||
private void syncTour(String selectedItem){
|
private void syncTour(String selectedItem){
|
||||||
beschreibungTableView.getItems().removeIf(s -> true); //Leert die Table View komplett
|
beschreibungTableView.getItems().removeIf(s -> true); //Leert die Table View komplett
|
||||||
beschreibungTableView.getItems().add(this.viewModel.getTour(selectedItem));
|
beschreibungTableView.getItems().add(this.viewModel.getTour(selectedItem));
|
||||||
|
mapImageView.setImage(this.viewModel.getImage(selectedItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncTourNamen(){
|
private void syncTourNamen(){
|
||||||
@ -163,6 +168,7 @@ public class TourplanerController implements Initializable {
|
|||||||
this.titleTextView.setText(ConfigHelper.getLangIniString("keinetourselected"));
|
this.titleTextView.setText(ConfigHelper.getLangIniString("keinetourselected"));
|
||||||
this.viewModel.delTour();
|
this.viewModel.delTour();
|
||||||
logTableView.setPlaceholder(new Label( ConfigHelper.getLangIniString("keinetourselected")));
|
logTableView.setPlaceholder(new Label( ConfigHelper.getLangIniString("keinetourselected")));
|
||||||
|
mapImageView.setImage(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +40,7 @@ public class ViewModel {
|
|||||||
* Bearbeitet eine bereits bestehende Tour
|
* Bearbeitet eine bereits bestehende Tour
|
||||||
* prüft ob eine tour ausgewählt ist
|
* prüft ob eine tour ausgewählt ist
|
||||||
*/
|
*/
|
||||||
public void editTour(){
|
public void editTour() throws IOException {
|
||||||
if (this.selectedTour == null){
|
if (this.selectedTour == null){
|
||||||
AlertHelper.warn(ConfigHelper.getLangIniString("achtung"),
|
AlertHelper.warn(ConfigHelper.getLangIniString("achtung"),
|
||||||
ConfigHelper.getLangIniString("keinetourselected"),
|
ConfigHelper.getLangIniString("keinetourselected"),
|
||||||
|
Reference in New Issue
Block a user