Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
#branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '16 2 * * 2'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
68 changes: 68 additions & 0 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# This workflow helps you trigger a SonarCloud analysis of your code and populates
# GitHub Code Scanning alerts with the vulnerabilities found.
# Free for open source project.

# 1. Login to SonarCloud.io using your GitHub account

# 2. Import your project on SonarCloud
# * Add your GitHub organization first, then add your repository as a new project.
# * Please note that many languages are eligible for automatic analysis,
# which means that the analysis will start automatically without the need to set up GitHub Actions.
# * This behavior can be changed in Administration > Analysis Method.
#
# 3. Follow the SonarCloud in-product tutorial
# * a. Copy/paste the Project Key and the Organization Key into the args parameter below
# (You'll find this information in SonarCloud. Click on "Information" at the bottom left)
#
# * b. Generate a new token and add it to your Github repository's secrets using the name SONAR_TOKEN
# (On SonarCloud, click on your avatar on top-right > My account > Security
# or go directly to https://sonarcloud.io/account/security/)

# Feel free to take a look at our documentation (https://docs.sonarcloud.io/getting-started/github/)
# or reach out to our community forum if you need some help (https://community.sonarsource.com/c/help/sc/9)

name: SonarCloud analysis

on:
push:
#branches: [ "master" ]
pull_request:
branches: [ "master" ]
workflow_dispatch:

permissions:
pull-requests: read # allows SonarCloud to decorate PRs with analysis results

jobs:
Analysis:
runs-on: ubuntu-latest

steps:
- name: Analyze with SonarCloud

# You can pin the exact commit or the version.
# uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049
uses: SonarSource/sonarcloud-github-action@de2e56b42aa84d0b1c5b622644ac17e505c9a049
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
with:
# Additional arguments for the sonarcloud scanner
args:
# Unique keys of your project and organization. You can find them in SonarCloud > Information (bottom-left menu)
# mandatory
-Dsonar.projectKey=${{ secrets.PROJECT_KEY }}
-Dsonar.organization=${{ secrets.ORGANIZATION_NAME }}
# Comma-separated paths to directories containing main source files.
#-Dsonar.sources= # optional, default is project base directory
# When you need the analysis to take place in a directory other than the one from which it was launched
#-Dsonar.projectBaseDir= # optional, default is .
# Comma-separated paths to directories containing test source files.
#-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/
# Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing.
#-Dsonar.verbose= # optional, default is false
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package de.doubleslash.keeptime.common;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javafx.scene.paint.Color;

public class RandomColorPicker {
private static final Logger LOG = LoggerFactory.getLogger(RandomColorPicker.class);

public static List<Color> colors = new ArrayList<>();

static {
try {
fillColorList();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

public static Color getRandomColor(List<Color> colorList) {

int rnd = new Random().nextInt(colorList.size());
return colorList.get(rnd);
}

private static void fillColorList() throws IllegalAccessException {
Field[] field = Color.class.getFields();
if (field != null) {
for (int i = 0; i < field.length; i++) {
Field f = field[i];
Object obj = f.get(null);
if (obj instanceof Color) {
colors.add((Color) obj);
}
}
}
}

public static Color chooseContrastColor(List<Color> availableColors, Color backgroundColor,Color hoverbackgroundColor) {

double divAdd = 0;
Color divColor = null;
int maxTries = 0;

while (divAdd < 1 && maxTries < 10) {
divColor = getUniqueColor(availableColors, backgroundColor, hoverbackgroundColor);
double divred = Math.abs(divColor.getRed() - backgroundColor.getRed());
double divgreen = Math.abs(divColor.getGreen() - backgroundColor.getGreen());
double divblue = Math.abs(divColor.getBlue() - backgroundColor.getBlue());
divAdd = divblue + divgreen + divred;
maxTries++;
}
return divColor;
}

public static Color getUniqueColor(List<Color> availableColors, Color backgroundColor, Color hoverbackgroundColor) {

List<Color> uniqueColorList = new ArrayList<>(colors);
uniqueColorList.remove(backgroundColor); // List should remove all already used colors.
uniqueColorList.remove(hoverbackgroundColor);
for (Color color : availableColors) {
for (int i = 0; i < uniqueColorList.size(); i++) {

if (color.toString().equals(uniqueColorList.get(i).toString())) {
uniqueColorList.remove(i);
}
}
}
if(uniqueColorList.isEmpty()){
LOG.info("Empty uniqueColorList return Black");
return Color.BLACK;
}
return getRandomColor(uniqueColorList);
}

}
4 changes: 3 additions & 1 deletion src/main/java/de/doubleslash/keeptime/common/Resources.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ public enum RESOURCE {

SVG_LICENSES_ICON("/svgs/closed-captioning.svg"),

ICON_MAIN("/icons/icon.png")
SVG_RANDOM_COLOR_BUTTON("/svgs/dice.svg"),

ICON_MAIN("/icons/icon.png"),

;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

package de.doubleslash.keeptime.view;

import static de.doubleslash.keeptime.view.ViewController.fontColorProperty;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
Expand All @@ -25,11 +30,17 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import de.doubleslash.keeptime.common.RandomColorPicker;
import de.doubleslash.keeptime.common.Resources;
import de.doubleslash.keeptime.common.SvgNodeProvider;
import de.doubleslash.keeptime.model.Model;
import de.doubleslash.keeptime.model.Project;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.SVGPath;

@Component
public class ManageProjectController {
Expand All @@ -56,6 +67,9 @@ public class ManageProjectController {
@FXML
private Spinner<Integer> sortIndexSpinner;

@FXML
private Button randomColorButton;

@FXML
private Label validateTextAlert;

Expand All @@ -73,6 +87,25 @@ private void initialize() {
sortIndexSpinner.getValueFactory().setValue(model.getAvailableProjects().size());
formValidProperty.bind(Bindings.createBooleanBinding(() -> !nameTextField.getText().isBlank(),nameTextField.textProperty()));
validateTextAlert.visibleProperty().bind(formValidProperty.not());
randomColorButton.setOnAction(event -> setRandomColor());

SVGPath calendarSvgPath = SvgNodeProvider.getSvgNodeWithScale(Resources.RESOURCE.SVG_RANDOM_COLOR_BUTTON, 0.04,
0.04);
calendarSvgPath.fillProperty().bind(fontColorProperty);
randomColorButton.setGraphic(calendarSvgPath);
}

private void setRandomColor() {
textFillColorPicker.setValue(
RandomColorPicker.chooseContrastColor( getProjectColorList(), model.defaultBackgroundColor.get(), model.hoverBackgroundColor.get()));
}

private List getProjectColorList() {
List<Color> colorList = new ArrayList<>();
for (Project project : model.getAllProjects()) {
colorList.add(project.getColor());
}
return colorList;
}

public void initializeWith(final Project project) {
Expand Down
9 changes: 8 additions & 1 deletion src/main/resources/layouts/manage-project.fxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.control.Label?>
Expand All @@ -9,6 +10,7 @@
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>

Expand All @@ -33,7 +35,6 @@
<Label text="IsWork:" GridPane.rowIndex="5" />
<Label text="SortIndex:" GridPane.rowIndex="6" />
<TextField fx:id="nameTextField" GridPane.columnIndex="1" />
<ColorPicker fx:id="textFillColorPicker" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<CheckBox fx:id="isWorkCheckBox" mnemonicParsing="false" selected="true" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Spinner fx:id="sortIndexSpinner" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<TextArea fx:id="descriptionTextArea" prefHeight="120.0" prefWidth="300.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
Expand All @@ -43,6 +44,12 @@
<Label disable="true" prefWidth="100.0" text="(will be matched at search)" wrapText="true" />
</children>
</VBox>
<HBox prefHeight="16.0" prefWidth="300.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
<children>
<ColorPicker fx:id="textFillColorPicker" />
<Button fx:id="randomColorButton" contentDisplay="GRAPHIC_ONLY" maxHeight="30.0" maxWidth="30.0" minHeight="25.0" minWidth="50.0" mnemonicParsing="false" prefHeight="20.0" prefWidth="30.0" />
</children>
</HBox>
<Label fx:id="validateTextAlert" prefHeight="17.0" prefWidth="201.0" text="Please enter a project name" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
<padding>
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/svgs/dice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package de.doubleslash.keeptime.common;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javafx.scene.paint.Color;

class RandomColorPickerTest {
@Test
public void shouldReturnBlackWhenAllColorsTakenAlready() {
RandomColorPicker.colors = List.of(Color.RED);

Assertions.assertEquals(Color.BLACK, RandomColorPicker.getUniqueColor(List.of(Color.RED), Color.BLUE, Color.YELLOW));
}

@Test
public void shouldReturnUniqueColorWhenGiveBackgroundAndProjectColor() {
RandomColorPicker.colors = new ArrayList<>(Arrays.asList(Color.RED, Color.BLUE, Color.GREEN, Color.GRAY));

Assertions.assertEquals(Color.GRAY,
RandomColorPicker.getUniqueColor(Arrays.asList(Color.RED, Color.GREEN), Color.BLUE,Color.YELLOW));
}

}