Premier commit - Mise en place de git sur le projet.
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
MCQFormQuizSheetParser/bin/
|
||||||
|
app/build
|
||||||
|
MCQFormQuizSheetParser/.settings
|
||||||
|
|
||||||
|
gradle/
|
||||||
|
gradlew
|
||||||
|
gradlew.bat
|
||||||
|
|
||||||
|
MCQFormQuizSheetParser/.classpath
|
||||||
|
MCQFormQuizSheetParser/.project
|
||||||
|
|
||||||
|
out.log
|
||||||
BIN
MCQFormQuizSheetParser/jOpenDocument-1.2.jar
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
package com.bernard.mcq.formQuiz;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jopendocument.dom.spreadsheet.Cell;
|
||||||
|
import org.jopendocument.dom.spreadsheet.Sheet;
|
||||||
|
import org.jopendocument.dom.spreadsheet.SpreadSheet;
|
||||||
|
|
||||||
|
public class MainParser {
|
||||||
|
|
||||||
|
static JFileChooser inputChooser;
|
||||||
|
static JFileChooser outputChooser;
|
||||||
|
|
||||||
|
public static final byte[] appBernardKey = { 0b00100010, 0b01001001 };
|
||||||
|
public static final byte[] bernardSignature = { 0b00011001, 0b01101101 };
|
||||||
|
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, FileNotFoundException {
|
||||||
|
|
||||||
|
System.setOut(new PrintStream(new FileOutputStream("out.log")));
|
||||||
|
|
||||||
|
inputChooser = new JFileChooser();
|
||||||
|
inputChooser.addChoosableFileFilter(new FileNameExtensionFilter("Libre office calc sheet", "ods"));
|
||||||
|
while (true) {
|
||||||
|
int returnVal = inputChooser.showOpenDialog(null);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File inputFile = inputChooser.getSelectedFile();
|
||||||
|
outputChooser = new JFileChooser();
|
||||||
|
outputChooser.addChoosableFileFilter(new FileNameExtensionFilter("Bernard file", "bernard"));
|
||||||
|
int returnVal2 = outputChooser.showSaveDialog(null);
|
||||||
|
if (returnVal2 == JFileChooser.APPROVE_OPTION) {
|
||||||
|
String outputName = outputChooser.getSelectedFile().getName();
|
||||||
|
outputName += !outputName.endsWith(".bernard") ? ".bernard" : "";
|
||||||
|
File saveDirectory = outputChooser.getCurrentDirectory();
|
||||||
|
String outQuizID;
|
||||||
|
do {
|
||||||
|
outQuizID = JOptionPane.showInputDialog(null, "What is the quiz's quizID ?", "QuizID ?",
|
||||||
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
|
} while (!outQuizID.matches("[0-9]+"));
|
||||||
|
int quizID = Integer.parseInt(outQuizID);
|
||||||
|
String name = JOptionPane.showInputDialog(null, "What is the quiz's name ?", "Name ?",
|
||||||
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
|
String author = JOptionPane.showInputDialog(null, "Who is the quiz's author ?", "Author ?",
|
||||||
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
|
Sheet sheet;
|
||||||
|
try {
|
||||||
|
sheet = SpreadSheet.createFromFile(inputFile).getSheet(0);
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
List<String> formsMarkers = new ArrayList<>();
|
||||||
|
while (true) {
|
||||||
|
Cell<SpreadSheet> cell = sheet.getCellAt(0, row);
|
||||||
|
System.out.println("\"" + cell.getTextValue() + "\"");
|
||||||
|
String tv = getCellContent(cell);
|
||||||
|
if (tv == null || tv.isEmpty())
|
||||||
|
break;
|
||||||
|
formsMarkers.add(cell.getTextValue());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
String endTag = formsMarkers.get(formsMarkers.size() - 1);
|
||||||
|
formsMarkers.remove(formsMarkers.size() - 1);
|
||||||
|
|
||||||
|
List<Map<Integer,List<String>>> verben = new ArrayList<>();
|
||||||
|
|
||||||
|
int col = 1;
|
||||||
|
int formID;
|
||||||
|
int tempFormID;
|
||||||
|
while (!sheet.getCellAt(col, 0).getTextValue().isEmpty()) {
|
||||||
|
//New Item
|
||||||
|
row = 0;
|
||||||
|
formID = -1;
|
||||||
|
Map<Integer,List<String>> forms = new HashMap<>();
|
||||||
|
|
||||||
|
String cellValue;
|
||||||
|
while (!(cellValue = getCellContent(sheet.getCellAt(col,row))).equals(endTag)) {
|
||||||
|
|
||||||
|
if ((tempFormID = formsMarkers.indexOf(cellValue))!=-1){
|
||||||
|
formID = tempFormID;
|
||||||
|
forms.put(formID, new ArrayList<String>());
|
||||||
|
}else if (cellValue != null && !cellValue.isEmpty() && forms.get(formID) != null)
|
||||||
|
forms.get(formID).add(cellValue);
|
||||||
|
row++;
|
||||||
|
System.out.println("Future test : ("+col+";"+row+")");
|
||||||
|
}
|
||||||
|
verben.add(forms);
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Final : ");
|
||||||
|
System.out.println(verben.toString());
|
||||||
|
|
||||||
|
// Save as quiz file
|
||||||
|
File saveFile = new File(saveDirectory, outputName);
|
||||||
|
if (saveFile.exists()) {
|
||||||
|
int returnVal3 = JOptionPane.showConfirmDialog(null,
|
||||||
|
"Do you really want to overwrite " + saveFile.getPath(), "Overwrite ?",
|
||||||
|
JOptionPane.YES_NO_OPTION);
|
||||||
|
if (returnVal3 != JOptionPane.YES_OPTION)
|
||||||
|
continue;
|
||||||
|
saveFile.delete();
|
||||||
|
}
|
||||||
|
if (saveFile.canWrite())
|
||||||
|
error(saveFile.getAbsolutePath() + " is unwritable !!!");
|
||||||
|
if (saveFile.isDirectory())
|
||||||
|
error(saveFile.getAbsolutePath() + " is a directory !!!");
|
||||||
|
if (!saveFile.exists()) {
|
||||||
|
saveFile.createNewFile();
|
||||||
|
}
|
||||||
|
DataOutputStream dos = new DataOutputStream(new FileOutputStream(saveFile));
|
||||||
|
|
||||||
|
// Writing Bernard signature
|
||||||
|
dos.write(bernardSignature);
|
||||||
|
|
||||||
|
// Writing Bernard key
|
||||||
|
dos.write(appBernardKey);
|
||||||
|
|
||||||
|
//QuizMetadata
|
||||||
|
|
||||||
|
dos.writeInt(name.getBytes().length);
|
||||||
|
dos.write(name.getBytes());
|
||||||
|
dos.writeInt(author.getBytes().length);
|
||||||
|
dos.write(author.getBytes());
|
||||||
|
dos.writeLong(0);
|
||||||
|
dos.writeInt(quizID);
|
||||||
|
dos.writeBoolean(false);
|
||||||
|
|
||||||
|
//QuizPayload
|
||||||
|
|
||||||
|
// Writing quizType key
|
||||||
|
dos.writeInt(quizID);
|
||||||
|
|
||||||
|
// Writing quiz
|
||||||
|
dos.writeInt(verben.size());
|
||||||
|
for (Map<Integer,List<String>> forms : verben) {
|
||||||
|
dos.writeInt(forms.size());
|
||||||
|
for (Map.Entry<Integer,List<String>> entry : forms.entrySet()) {
|
||||||
|
if (entry.getValue().size() <= 0) {
|
||||||
|
dos.writeInt(-1);//FormID
|
||||||
|
dos.writeInt(0);
|
||||||
|
System.err.println("This clause should not be executed");
|
||||||
|
} else {
|
||||||
|
dos.writeInt(entry.getKey());
|
||||||
|
dos.writeInt(entry.getValue().get(0).getBytes(UTF_8).length);
|
||||||
|
dos.write(entry.getValue().get(0).getBytes(UTF_8));
|
||||||
|
dos.writeInt(entry.getValue().size() - 1);
|
||||||
|
for (int i = 1; i < entry.getValue().size(); i++) {
|
||||||
|
dos.writeInt(entry.getValue().get(i).getBytes(UTF_8).length);
|
||||||
|
dos.write(entry.getValue().get(i).getBytes(UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dos.close();
|
||||||
|
|
||||||
|
int resultVal4 = JOptionPane.showConfirmDialog(null,
|
||||||
|
"Fichier <20>crit !!! Voulez vous parser un autre document ?", "Done",
|
||||||
|
JOptionPane.YES_NO_OPTION);
|
||||||
|
|
||||||
|
if (resultVal4 != JOptionPane.YES_OPTION)
|
||||||
|
break;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
error("Impossible de lire le fichier , " + e.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Bye !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Bye !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public static String getCellContent(Cell<SpreadSheet> cell){
|
||||||
|
try{
|
||||||
|
//String toString = new String(((Element)cell.getElement().getContent(0)).getContent(0).getValue().getBytes(UTF_8),UTF_8);
|
||||||
|
//System.out.println(toString + Arrays.toString(toString.getBytes(UTF_8)));
|
||||||
|
return cell.getTextValue();//toString;
|
||||||
|
}catch(Exception e){
|
||||||
|
System.err.println("(Un)expected Exception : " + e.getClass().getName());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String text) {
|
||||||
|
System.out.println(text);
|
||||||
|
JOptionPane.showMessageDialog(null, text, "Error !!!!!", JOptionPane.ERROR_MESSAGE);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
88
MCQinator.svg
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="480"
|
||||||
|
height="480"
|
||||||
|
viewBox="0 0 127 127"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.1 r15371"
|
||||||
|
sodipodi:docname="MCQinator.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.98994949"
|
||||||
|
inkscape:cx="212.89874"
|
||||||
|
inkscape:cy="220.30968"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
width="480px"
|
||||||
|
inkscape:window-width="1366"
|
||||||
|
inkscape:window-height="709"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-170)">
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#01ff96;stroke-width:8.76500034;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 7.4835468,292.18915 V 177.26325 L 61.684861,208.5564 119.74536,175.03515 v 117.154"
|
||||||
|
id="path49"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#01ff96;stroke-width:8.76500034;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path856"
|
||||||
|
sodipodi:type="arc"
|
||||||
|
sodipodi:cx="62.941971"
|
||||||
|
sodipodi:cy="254.63779"
|
||||||
|
sodipodi:rx="37.01683"
|
||||||
|
sodipodi:ry="37.01683"
|
||||||
|
sodipodi:start="0.61086524"
|
||||||
|
sodipodi:end="5.6723201"
|
||||||
|
d="m 93.264383,275.86977 a 37.01683,37.01683 0 0 1 -41.453588,14.0716 37.01683,37.01683 0 0 1 -25.885655,-35.30358 37.01683,37.01683 0 0 1 25.885656,-35.30358 37.01683,37.01683 0 0 1 41.453588,14.0716"
|
||||||
|
sodipodi:open="true" />
|
||||||
|
<ellipse
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#01ff96;stroke-width:8.76500034;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path860"
|
||||||
|
cx="62.541065"
|
||||||
|
cy="253.83597"
|
||||||
|
rx="21.114292"
|
||||||
|
ry="20.713387" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#01ff96;stroke-width:7.86499977;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 68.15373,263.85858 79.379048,277.7566"
|
||||||
|
id="path862"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
27
app/build.gradle
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 28
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.bernard.mcqinator"
|
||||||
|
minSdkVersion 15
|
||||||
|
targetSdkVersion 28
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
|
}
|
||||||
53
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.bernard.mcqinator">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/DarkTheme"
|
||||||
|
android:fullBackupContent="true">
|
||||||
|
<activity
|
||||||
|
android:name=".view.activities.MainActivity"
|
||||||
|
android:screenOrientation="portrait">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".view.activities.ChoosingQuizActivity"
|
||||||
|
android:screenOrientation="portrait" />
|
||||||
|
<activity android:name=".view.activities.ChoosingQuizToEditActivity" />
|
||||||
|
<activity
|
||||||
|
android:name=".view.activities.CreateQuizActivity"
|
||||||
|
android:noHistory="true" />
|
||||||
|
<activity android:name=".view.quizEditing.formQuiz.EditFormQuiz" />
|
||||||
|
<activity android:name=".view.quizEditing.formQuiz.EditFormQuizItem" />
|
||||||
|
<activity android:name=".view.activities.QuizManagerActivity" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data
|
||||||
|
android:scheme="http"
|
||||||
|
android:host="www.bernard.com"
|
||||||
|
android:pathPrefix="/repositories/mcqinator/" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name=".view.activities.fragenActivities.BlocFrageActivity" />
|
||||||
|
<activity android:name=".view.activities.fragenActivities.TextFrageActivity" />
|
||||||
|
<activity android:name=".view.activities.ConfiguringQuizActivity" />
|
||||||
|
<activity
|
||||||
|
android:name=".view.activities.congratsActivity.DEVerbenCongratsActivity"
|
||||||
|
android:label="@string/title_activity_deverben_congrats" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
98
app/src/main/java/com/bernard/mcqinator/EditQuizDEVerben.old
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package com.bernard.qcminator.editQuiz;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.bernard.qcminator.ChoosingQuizToEditActivity;
|
||||||
|
import com.bernard.qcminator.R;
|
||||||
|
import com.bernard.qcminator.quiz.DEVerbenQuiz;
|
||||||
|
import com.bernard.qcminator.quiz.Quiz;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class EditQuizDEVerben extends ListActivity {
|
||||||
|
|
||||||
|
public static final int VERBE_NEW = 0x5603B6BD;
|
||||||
|
public static final int VERBE_CHANGE = 0x68E0B3A1;
|
||||||
|
|
||||||
|
DEVerbenQuiz quiz;
|
||||||
|
DEVerbenQuiz.VerbeAdapter adapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_edit_quiz_deverben);
|
||||||
|
Intent i = getIntent();
|
||||||
|
int fileID = i.getIntExtra(ChoosingQuizToEditActivity.QUIZ_FILEID,-1);
|
||||||
|
Quiz q;
|
||||||
|
try {
|
||||||
|
q = Quiz.getFromFile(this.openFileInput("quiz_"+fileID+".bernard"),fileID);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("Data error","Quiz filename invalid",e);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!(q instanceof DEVerbenQuiz)){
|
||||||
|
Log.e("Data error","Quiz type invalid");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quiz = (DEVerbenQuiz)q;
|
||||||
|
adapter = quiz.new VerbeAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
|
||||||
|
Button neueVerbe = (Button)findViewById(R.id.neueVerbeButton);
|
||||||
|
neueVerbe.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(EditQuizDEVerben.this, EditQuizDEVerbenVerbe.class);
|
||||||
|
i.putExtra(EditQuizDEVerbenVerbe.TO_EDIT_VERBE,(Parcelable) null);
|
||||||
|
startActivityForResult(i,VERBE_NEW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button doneButton = (Button)findViewById(R.id.doneButton);
|
||||||
|
doneButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
quiz.saveQuiz(EditQuizDEVerben.this);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if(requestCode == VERBE_NEW && resultCode == RESULT_OK){
|
||||||
|
DEVerbenQuiz.Item v = data.getParcelableExtra(EditQuizDEVerbenVerbe.EDITED_VERBE);
|
||||||
|
quiz.addItem(v);
|
||||||
|
quiz.saveQuiz(this);
|
||||||
|
adapter = quiz.new VerbeAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
}
|
||||||
|
if(requestCode == VERBE_CHANGE && resultCode == RESULT_OK){
|
||||||
|
DEVerbenQuiz.Item v = data.getParcelableExtra(EditQuizDEVerbenVerbe.EDITED_VERBE);
|
||||||
|
int pos = data.getIntExtra(EditQuizDEVerbenVerbe.VERBE_POSITION,0);
|
||||||
|
quiz.setItem(pos,v);
|
||||||
|
quiz.saveQuiz(this);
|
||||||
|
adapter = quiz.new VerbeAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
Intent i = new Intent(EditQuizDEVerben.this, EditQuizDEVerbenVerbe.class);
|
||||||
|
i.putExtra(EditQuizDEVerbenVerbe.TO_EDIT_VERBE,adapter.getItem(position));
|
||||||
|
i.putExtra(EditQuizDEVerbenVerbe.VERBE_POSITION,position);
|
||||||
|
startActivityForResult(i,VERBE_CHANGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.bernard.mcqinator.api;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 22/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class IdentifiedQuiz <F extends Frage,I extends Frage.Identifier> {
|
||||||
|
|
||||||
|
private final F[] fragen;
|
||||||
|
private final I identifier;
|
||||||
|
|
||||||
|
public IdentifiedQuiz(F[] fragen, I identifier) {
|
||||||
|
this.fragen = fragen;
|
||||||
|
this.identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public F[] getFragen() {
|
||||||
|
return fragen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public F getFrage(int pos) {
|
||||||
|
return fragen[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
public I getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
181
app/src/main/java/com/bernard/mcqinator/api/QuizMetadata.java
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
package com.bernard.mcqinator.api;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.FormQuizStat;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
import com.bernard.mcqinator.api.quiz.DEVerbenQuiz;
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
import com.bernard.mcqinator.view.activities.congratsActivity.DEVerbenCongratsActivity;
|
||||||
|
import com.bernard.mcqinator.view.quizEditing.formQuiz.EditFormQuiz;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class QuizMetadata implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String author;
|
||||||
|
private long fileID;
|
||||||
|
private Type type;
|
||||||
|
private boolean editable;
|
||||||
|
|
||||||
|
public QuizMetadata(String name, String author, long fileID, Type type, boolean editable) {
|
||||||
|
this.name = name;
|
||||||
|
this.author = author;
|
||||||
|
this.fileID = fileID;
|
||||||
|
this.type = type;
|
||||||
|
this.editable = editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuizMetadata() {}// For serialization
|
||||||
|
|
||||||
|
|
||||||
|
//////////// File methods ////////////
|
||||||
|
|
||||||
|
public void read(DataInputStream fin) throws IOException{
|
||||||
|
byte[] nameBytes = new byte[fin.readInt()];
|
||||||
|
if(fin.read(nameBytes) != nameBytes.length)throw new IOException("Corrupted data : announced name bytes count dont match found");
|
||||||
|
this.name = new String(nameBytes);
|
||||||
|
byte[] authorBytes = new byte[fin.readInt()];
|
||||||
|
if(fin.read(authorBytes) != authorBytes.length)throw new IOException("Corrupted data : announced author bytes count dont match found");
|
||||||
|
this.author = new String(authorBytes);
|
||||||
|
this.fileID = fin.readLong();
|
||||||
|
this.type = Type.getTypeFromID(fin.readInt());
|
||||||
|
this.editable = fin.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(DataOutputStream fos) throws IOException{
|
||||||
|
fos.writeInt(this.name.getBytes().length);
|
||||||
|
fos.write(this.name.getBytes());
|
||||||
|
fos.writeInt(this.author.getBytes().length);
|
||||||
|
fos.write(this.author.getBytes());
|
||||||
|
fos.writeLong(this.fileID);
|
||||||
|
fos.writeInt(this.type.getId());
|
||||||
|
fos.writeBoolean(this.editable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Getters and Setters ////////////
|
||||||
|
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(String author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFileID() {
|
||||||
|
return fileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileID(long fileID) {
|
||||||
|
this.fileID = fileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEditable() {
|
||||||
|
return editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditable(boolean editable) {
|
||||||
|
this.editable = editable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Internal Classes ////////////
|
||||||
|
|
||||||
|
public enum Type{
|
||||||
|
DEVerben(DEVerbenQuiz.class, FormQuizStat.class, EditFormQuiz.class, DEVerbenCongratsActivity.class, R.drawable.de_verben_quiz,0);
|
||||||
|
|
||||||
|
final Class<? extends Quiz> quizClass;
|
||||||
|
final Class<? extends QuizStat> quizStatClass;
|
||||||
|
final Class<? extends Activity> editActivityClass;
|
||||||
|
final Class<? extends Activity> congratsActivityClass;
|
||||||
|
final int quizIconID;
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
Type(Class<? extends Quiz> quizClass, Class<? extends QuizStat> quizStatClass, Class<? extends Activity> editActivityClass, Class<? extends Activity> congratsActivityClass, int quizIconID, int id) {
|
||||||
|
this.quizClass = quizClass;
|
||||||
|
this.quizStatClass = quizStatClass;
|
||||||
|
this.editActivityClass = editActivityClass;
|
||||||
|
this.congratsActivityClass = congratsActivityClass;
|
||||||
|
this.quizIconID = quizIconID;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type(Class<? extends Quiz> quizClass, Class<? extends QuizStat> quizStatClass, Class<? extends Activity> editActivityClass, Class<? extends Activity> congratsActivityClass, int id) {
|
||||||
|
this(quizClass,quizStatClass,editActivityClass,congratsActivityClass,R.drawable.default_quiz_icon,id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Quiz> getQuizClass() {
|
||||||
|
return quizClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends QuizStat> getQuizStatClass() {
|
||||||
|
return quizStatClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Activity> getEditActivityClass() {
|
||||||
|
return editActivityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends Activity> getCongratsActivityClass(){
|
||||||
|
return congratsActivityClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQuizIconID() {
|
||||||
|
return quizIconID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Type getTypeFromID(int id){
|
||||||
|
for (Type t:Type.values()) {
|
||||||
|
if(t.getId() == id)
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Misc ///////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "QuizMetadata{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", author='" + author + '\'' +
|
||||||
|
", fileID=" + fileID +
|
||||||
|
", type=" + type +
|
||||||
|
", editable=" + editable +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,249 @@
|
|||||||
|
package com.bernard.mcqinator.api.frageable;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.fragen.BlocFrage;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
import com.bernard.mcqinator.view.activities.MainActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.BlocFrageActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 05/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface BlocFrageable<S extends QuizStat,ID extends Frage.Identifier> extends Frageable<BlocFrageable.BlocData,BlocFrage.Reply,BlocFrageable.BlocConfigurator,S,ID,BlocFrage> {
|
||||||
|
|
||||||
|
int[] useableBlocCount = {2,3,4,6,8};
|
||||||
|
Class <? extends Frageable.Configurator> CONFIGURATOR = BlocConfigurator.class;
|
||||||
|
String LAST_BLOC_VALUE = "com.bernard.qcminator.LAST_BLOC_VALUE";
|
||||||
|
String LAST_FRAGE_COUNT = "com.bernard.qcminator.LAST_BLOC_FRAGE_COUNT";
|
||||||
|
int DEFAULT_FRAGE_COUNT = 10;
|
||||||
|
int DEFAULT_FRAGE_COUNT_MAX = 50;
|
||||||
|
int DEFAULT_BLOC_VALUE = 2;
|
||||||
|
|
||||||
|
class BlocData extends Frageable.Data{
|
||||||
|
public final int blockNumber;
|
||||||
|
public final int length;
|
||||||
|
|
||||||
|
|
||||||
|
public BlocData(int blockNumber, int length) {
|
||||||
|
this.blockNumber = blockNumber;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockNumber() {
|
||||||
|
return blockNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends FrageActivity<? extends Frage>> getFrageActivityClass() {
|
||||||
|
return BlocFrageActivity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeInt(blockNumber);
|
||||||
|
dest.writeInt(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<BlocData> CREATOR = new Parcelable.Creator<BlocData>(){
|
||||||
|
@Override
|
||||||
|
public BlocData createFromParcel(Parcel source) {
|
||||||
|
return new BlocData(source.readInt(),source.readInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlocData[] newArray(int size) {
|
||||||
|
return new BlocData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlocConfigurator extends Frageable.Configurator{
|
||||||
|
public int lastBlocCountIndex = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View attachConfigLayout(final Activity a,ViewGroup frame) {
|
||||||
|
final View layout = a.getLayoutInflater().inflate(R.layout.bloc_frage_options_layout,frame);
|
||||||
|
final Button blocCountButton = layout.findViewById(R.id.blocCount);
|
||||||
|
final TextView frageCountText = layout.findViewById(R.id.frageCountText);
|
||||||
|
final SeekBar frageCountBar = layout.findViewById(R.id.frageCount);
|
||||||
|
|
||||||
|
SharedPreferences preferences = a.getSharedPreferences(MainActivity.PREFERENCES_FILE_KEY,Context.MODE_PRIVATE);
|
||||||
|
lastBlocCountIndex = preferences.getInt(LAST_BLOC_VALUE,DEFAULT_BLOC_VALUE);
|
||||||
|
int realBlocCount = (lastBlocCountIndex>=0)?useableBlocCount[lastBlocCountIndex]:-lastBlocCountIndex;
|
||||||
|
|
||||||
|
blocCountButton.setText(a.getResources().getString(R.string.blocPerFrage,Integer.toString(realBlocCount,10)));
|
||||||
|
|
||||||
|
blocCountButton.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
builder.setTitle(R.string.blocCountAsk);
|
||||||
|
final EditText blocCountPrompt = new EditText(a);
|
||||||
|
blocCountPrompt.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
builder.setView(blocCountPrompt);
|
||||||
|
builder.setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
try {
|
||||||
|
int n = Integer.parseInt(blocCountPrompt.getText().toString(), 10);
|
||||||
|
lastBlocCountIndex = -n;
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.e("BlocCountDialog","Cannot read data",e);
|
||||||
|
Toast.makeText(a, R.string.failedSettingBlocCountValue, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
int realBlocCount = (lastBlocCountIndex>=0)?useableBlocCount[lastBlocCountIndex]:-lastBlocCountIndex;
|
||||||
|
blocCountButton.setText(a.getResources().getString(R.string.blocPerFrage,Integer.toString(realBlocCount,10)));
|
||||||
|
|
||||||
|
if(realBlocCount > 10){
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
builder.setTitle(R.string.achtung);
|
||||||
|
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||||
|
builder.setPositiveButton(android.R.string.ok,null);
|
||||||
|
TextView texte = new TextView(a);
|
||||||
|
texte.setText(R.string.blocCountABitHigh);
|
||||||
|
builder.setView(texte);
|
||||||
|
builder.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(android.R.string.no,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
blocCountButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Log.v("BCButton","simple click !");
|
||||||
|
lastBlocCountIndex = (lastBlocCountIndex < 0)?DEFAULT_BLOC_VALUE:(lastBlocCountIndex + 1 >= useableBlocCount.length)?0:lastBlocCountIndex+1;
|
||||||
|
int realBlocCount = (lastBlocCountIndex>=0)?useableBlocCount[lastBlocCountIndex]:-lastBlocCountIndex;
|
||||||
|
|
||||||
|
blocCountButton.setText(a.getResources().getString(R.string.blocPerFrage,Integer.toString(realBlocCount,10)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frageCountBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
frageCountText.setText(a.getResources().getString(R.string.fragCount,progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
View.OnLongClickListener frageCountLongListener = new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
Log.v("frageCount","looooooooooooong");
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
builder.setTitle(R.string.frageCountAsk);
|
||||||
|
final EditText frageCountPrompt = new EditText(a);
|
||||||
|
frageCountPrompt.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
builder.setView(frageCountPrompt);
|
||||||
|
builder.setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
try {
|
||||||
|
int n = Integer.parseInt(frageCountPrompt.getText().toString(), 10);
|
||||||
|
if(n>DEFAULT_FRAGE_COUNT_MAX)
|
||||||
|
frageCountBar.setMax(n);
|
||||||
|
else
|
||||||
|
frageCountBar.setMax(DEFAULT_FRAGE_COUNT_MAX);
|
||||||
|
frageCountBar.setProgress(n);
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.e("FrageCountDialog","Cannot read data",e);
|
||||||
|
Toast.makeText(a, R.string.failedSettingFrageCountValue, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(android.R.string.no,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
frageCountText.setLongClickable(true);
|
||||||
|
frageCountBar.setLongClickable(true);
|
||||||
|
|
||||||
|
frageCountBar.setOnLongClickListener(frageCountLongListener);
|
||||||
|
frageCountText.setOnLongClickListener(frageCountLongListener);
|
||||||
|
|
||||||
|
frageCountBar.setProgress(preferences.getInt(LAST_FRAGE_COUNT,DEFAULT_FRAGE_COUNT));
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTypStringID() {
|
||||||
|
return R.string.blocQuiz;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconDrawableID() {
|
||||||
|
return R.drawable.bloc_quiz_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data genDataFromConfigLayout(View v) {
|
||||||
|
SeekBar fC = v.findViewById(R.id.frageCount);
|
||||||
|
int realBlocCount = (lastBlocCountIndex>=0)?useableBlocCount[lastBlocCountIndex]:-lastBlocCountIndex;
|
||||||
|
BlocData bdata = new BlocData(realBlocCount,fC.getProgress());
|
||||||
|
Log.v("BlocData","Selected : "+bdata.blockNumber+","+bdata.length);
|
||||||
|
return bdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.bernard.mcqinator.api.frageable;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.IdentifiedQuiz;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 05/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface Frageable<FrData extends Frageable.Data,FrReply extends Frage.Reply,QzConfig extends Frageable.Configurator,S extends QuizStat,ID extends Frage.Identifier,F extends Frage> {
|
||||||
|
|
||||||
|
IdentifiedQuiz<F,ID> genFragen(S stat, FrData frageData, Context context, ProgressDialog wait);
|
||||||
|
S updateStats(S oldStats, List<FrReply> replies, ID identifier);
|
||||||
|
|
||||||
|
//LATER remove parcelable
|
||||||
|
abstract class Data implements Parcelable {
|
||||||
|
public abstract Class<? extends FrageActivity<? extends Frage>> getFrageActivityClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
//LATER move to view package
|
||||||
|
abstract class Configurator{
|
||||||
|
public abstract int getTypStringID();
|
||||||
|
|
||||||
|
public abstract int getIconDrawableID();
|
||||||
|
|
||||||
|
public abstract View attachConfigLayout(Activity a,ViewGroup frame);
|
||||||
|
|
||||||
|
public abstract Frageable.Data genDataFromConfigLayout(View v);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
package com.bernard.mcqinator.api.frageable;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
import com.bernard.mcqinator.api.fragen.TextFrage;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
import com.bernard.mcqinator.view.activities.MainActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.TextFrageActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mysaa
|
||||||
|
* @date on 3/13/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface TextFrageable<S extends QuizStat,ID extends Frage.Identifier> extends Frageable<TextFrageable.TextData,TextFrage.Reply,TextFrageable.TextConfigurator,S,ID,TextFrage>{
|
||||||
|
|
||||||
|
String LAST_FRAGE_COUNT = "com.bernard.qcminator.LAST_TEXT_FRAGE_COUNT";
|
||||||
|
int DEFAULT_FRAGE_COUNT = 10;
|
||||||
|
int DEFAULT_FRAGE_COUNT_MAX = 50;
|
||||||
|
|
||||||
|
|
||||||
|
class TextData extends Frageable.Data{
|
||||||
|
public final int length;
|
||||||
|
|
||||||
|
|
||||||
|
public TextData(int length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends FrageActivity<? extends Frage>> getFrageActivityClass() {
|
||||||
|
return TextFrageActivity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeInt(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<TextFrageable.TextData> CREATOR = new Parcelable.Creator<TextFrageable.TextData>(){
|
||||||
|
@Override
|
||||||
|
public TextFrageable.TextData createFromParcel(Parcel source) {
|
||||||
|
return new TextFrageable.TextData(source.readInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextFrageable.TextData[] newArray(int size) {
|
||||||
|
return new TextFrageable.TextData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextConfigurator extends Frageable.Configurator{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View attachConfigLayout(final Activity a, ViewGroup frame) {
|
||||||
|
final View layout = a.getLayoutInflater().inflate(R.layout.text_frage_options_layout,frame);
|
||||||
|
final TextView frageCountText = layout.findViewById(R.id.frageCountText);
|
||||||
|
final SeekBar frageCountBar = layout.findViewById(R.id.frageCount);
|
||||||
|
|
||||||
|
frageCountBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
frageCountText.setText(a.getResources().getString(R.string.fragCount,progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
View.OnLongClickListener frageCountLongListener = new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
Log.v("frageCount","looooooooooooong");
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(a);
|
||||||
|
builder.setTitle(R.string.frageCountAsk);
|
||||||
|
final EditText frageCountPrompt = new EditText(a);
|
||||||
|
frageCountPrompt.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
|
builder.setView(frageCountPrompt);
|
||||||
|
builder.setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
try {
|
||||||
|
int n = Integer.parseInt(frageCountPrompt.getText().toString(), 10);
|
||||||
|
if(n>DEFAULT_FRAGE_COUNT_MAX)
|
||||||
|
frageCountBar.setMax(n);
|
||||||
|
else
|
||||||
|
frageCountBar.setMax(DEFAULT_FRAGE_COUNT_MAX);
|
||||||
|
frageCountBar.setProgress(n);
|
||||||
|
}catch(Exception e){
|
||||||
|
Log.e("FrageCountDialog","Cannot read data",e);
|
||||||
|
Toast.makeText(a, R.string.failedSettingFrageCountValue, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(android.R.string.no,new DialogInterface.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
frageCountText.setLongClickable(true);
|
||||||
|
frageCountBar.setLongClickable(true);
|
||||||
|
|
||||||
|
frageCountBar.setOnLongClickListener(frageCountLongListener);
|
||||||
|
frageCountText.setOnLongClickListener(frageCountLongListener);
|
||||||
|
|
||||||
|
SharedPreferences preferences = a.getSharedPreferences(MainActivity.PREFERENCES_FILE_KEY,Context.MODE_PRIVATE);
|
||||||
|
|
||||||
|
frageCountBar.setProgress(preferences.getInt(LAST_FRAGE_COUNT,DEFAULT_FRAGE_COUNT));
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTypStringID() {
|
||||||
|
return R.string.blocQuiz;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconDrawableID() {
|
||||||
|
return R.drawable.bloc_quiz_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Data genDataFromConfigLayout(View v) {
|
||||||
|
SeekBar fC = v.findViewById(R.id.frageCount);
|
||||||
|
return new TextData(fC.getProgress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
package com.bernard.mcqinator.api.fragen;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 04/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BlocFrage extends Frage{
|
||||||
|
private final String frage;
|
||||||
|
private final String richtigAntwort;
|
||||||
|
private final String[] falshAntworte;
|
||||||
|
|
||||||
|
public BlocFrage(String frage, String richtigAntwort, String[] falshAntworte) {
|
||||||
|
this.frage = frage;
|
||||||
|
this.richtigAntwort = richtigAntwort;
|
||||||
|
this.falshAntworte = falshAntworte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFrage() {
|
||||||
|
return frage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRichtigAntwort() {
|
||||||
|
return richtigAntwort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getFalshAntworte() {
|
||||||
|
return falshAntworte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<BlocFrage> CREATOR = new Parcelable.Creator<BlocFrage>() {
|
||||||
|
@Override
|
||||||
|
public BlocFrage createFromParcel(Parcel source) {
|
||||||
|
String frage = source.readString();
|
||||||
|
String richtigAntwort = source.readString();
|
||||||
|
String[] falshAntworte = new String[source.readInt()];
|
||||||
|
source.readStringArray(falshAntworte);
|
||||||
|
return new BlocFrage(frage,richtigAntwort,falshAntworte);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlocFrage[] newArray(int size) {
|
||||||
|
return new BlocFrage[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {return 0;}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(frage);
|
||||||
|
dest.writeString(richtigAntwort);
|
||||||
|
dest.writeInt(falshAntworte.length);
|
||||||
|
dest.writeStringArray(falshAntworte);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Frage.Reply> getReplyClass() {
|
||||||
|
return Reply.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "BlocFrage{" +
|
||||||
|
"frage='" + frage + '\'' +
|
||||||
|
", richtigAntwort='" + richtigAntwort + '\'' +
|
||||||
|
", falshAntworte=" + Arrays.toString(falshAntworte) +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Reply extends Frage.Reply{
|
||||||
|
final String answered;
|
||||||
|
|
||||||
|
public Reply(String answered) {
|
||||||
|
this.answered = answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAnswered() {
|
||||||
|
return answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<BlocFrage.Reply> CREATOR = new BlocFrage.Creator<BlocFrage.Reply>() {
|
||||||
|
public BlocFrage.Reply createFromParcel(Parcel source) {
|
||||||
|
return new BlocFrage.Reply(source.readString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reply[] newArray(int size) {
|
||||||
|
return new Reply[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {return 0;}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(answered);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.bernard.mcqinator.api.fragen;
|
||||||
|
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.BlocFrageActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 04/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class Frage implements Parcelable {
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
BLOC(BlocFrageActivity.class);
|
||||||
|
final Class<? extends FrageActivity> frageActivity;
|
||||||
|
|
||||||
|
Type(Class<? extends FrageActivity> frageActivity) {
|
||||||
|
this.frageActivity = frageActivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<? extends FrageActivity> getFrageActivity() {
|
||||||
|
return frageActivity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Class<? extends Reply> getReplyClass();
|
||||||
|
|
||||||
|
public abstract static class Reply implements Parcelable{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class Identifier {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
package com.bernard.mcqinator.api.fragen;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mysaa
|
||||||
|
* @date on 3/13/18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TextFrage extends Frage {
|
||||||
|
private final String frage;
|
||||||
|
private final String richtigAntwort;
|
||||||
|
|
||||||
|
public TextFrage(String frage, String richtigAntwort) {
|
||||||
|
this.frage = frage;
|
||||||
|
this.richtigAntwort = richtigAntwort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFrage() {
|
||||||
|
return frage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRichtigAntwort() {
|
||||||
|
return richtigAntwort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<TextFrage> CREATOR = new Parcelable.Creator<TextFrage>() {
|
||||||
|
@Override
|
||||||
|
public TextFrage createFromParcel(Parcel source) {
|
||||||
|
String frage = source.readString();
|
||||||
|
String richtigAntwort = source.readString();
|
||||||
|
return new TextFrage(frage,richtigAntwort);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextFrage[] newArray(int size) {
|
||||||
|
return new TextFrage[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {return 0;}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(frage);
|
||||||
|
dest.writeString(richtigAntwort);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Frage.Reply> getReplyClass() {
|
||||||
|
return TextFrage.Reply.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "BlocFrage{" +
|
||||||
|
"frage='" + frage + '\'' +
|
||||||
|
", richtigAntwort='" + richtigAntwort + '\'' +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Reply extends Frage.Reply{
|
||||||
|
final String answered;
|
||||||
|
|
||||||
|
public Reply(String answered) {
|
||||||
|
this.answered = answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAnswered() {
|
||||||
|
return answered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parcelable.Creator<TextFrage.Reply> CREATOR = new TextFrage.Creator<TextFrage.Reply>() {
|
||||||
|
public TextFrage.Reply createFromParcel(Parcel source) {
|
||||||
|
return new TextFrage.Reply(source.readString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextFrage.Reply[] newArray(int size) {
|
||||||
|
return new TextFrage.Reply[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {return 0;}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(answered);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
package com.bernard.mcqinator.api.fragenStats;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.quiz.FormQuiz;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 26/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FormQuizStat extends QuizStat<FormQuiz> {
|
||||||
|
/* TODO pass to formquiz */
|
||||||
|
protected volatile int failSum;
|
||||||
|
protected volatile int[] failSums;
|
||||||
|
protected volatile int[][] failsSum;
|
||||||
|
protected volatile int[][][] failsSums;
|
||||||
|
protected volatile int[][][][] fails;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void genDefault(FormQuiz q) {
|
||||||
|
FormQuiz.Item[] items = q.getItems();
|
||||||
|
fails = new int[items.length][][][];
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
fails[i] = new int[items[i].getForms().length][][];
|
||||||
|
for (int j = 0; j < items[i].getForms().length; j++) {
|
||||||
|
fails[i][j] = new int[items[i].getForms().length - 1][];
|
||||||
|
for (int k = 0; k < items[i].getForms().length - 1; k++) {
|
||||||
|
int[] current = new int[items[i].getForms()[j].getFalshe().length];
|
||||||
|
Arrays.fill(current,1);
|
||||||
|
fails[i][j][k] = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genVolatiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(DataInputStream dis) throws IOException {
|
||||||
|
fails = new int[dis.readInt()][][][];
|
||||||
|
for (int i = 0; i < fails.length; i++) {
|
||||||
|
fails[i] = new int[dis.readInt()][][];
|
||||||
|
for (int j = 0; j < fails[i].length; j++) {
|
||||||
|
fails[i][j] = new int[dis.readInt()][];
|
||||||
|
for (int k = 0; k < fails[i][j].length; k++) {
|
||||||
|
fails[i][j][k] = new int[dis.readInt()];
|
||||||
|
for (int l = 0; l < fails[i][j][k].length; l++)
|
||||||
|
fails[i][j][k][l] = dis.readInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genVolatiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream dos) throws IOException {
|
||||||
|
dos.writeInt(fails.length);
|
||||||
|
for (int[][][] fails1:fails) {
|
||||||
|
dos.writeInt(fails1.length);
|
||||||
|
for (int[][] fails2:fails1) {
|
||||||
|
dos.writeInt(fails2.length);
|
||||||
|
for (int[] fails3:fails2) {
|
||||||
|
dos.writeInt(fails3.length);
|
||||||
|
for (int fails4 : fails3)
|
||||||
|
dos.writeInt(fails4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void genVolatiles(){
|
||||||
|
failSum = 0;
|
||||||
|
failSums = new int[fails.length];
|
||||||
|
failsSum = new int[fails.length][];
|
||||||
|
failsSums = new int[fails.length][][];
|
||||||
|
for (int i = 0; i < fails.length; i++) {
|
||||||
|
failSums[i] = 0;
|
||||||
|
failsSum[i] = new int[fails[i].length];
|
||||||
|
failsSums[i] = new int[fails[i].length][];
|
||||||
|
for (int j = 0; j < fails[i].length; j++) {
|
||||||
|
failsSum[i][j] = 0;
|
||||||
|
failsSums[i][j] = new int[fails[i][j].length];
|
||||||
|
for (int k = 0; k < fails[i][j].length; k++) {
|
||||||
|
failsSums[i][j][k] = 0;
|
||||||
|
for (int l = 0; l < fails[i][j][k].length; l++)
|
||||||
|
failsSums[i][j][k] += fails[i][j][k][l];
|
||||||
|
failsSum[i][j] += failsSums[i][j][k];
|
||||||
|
}
|
||||||
|
failSums[i] += failsSum[i][j];
|
||||||
|
}
|
||||||
|
failSum += failSums[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int failSum(){
|
||||||
|
return failSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int failSum(int item){
|
||||||
|
return failSums[item];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int failSum(int item,int form){
|
||||||
|
return failsSum[item][form];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int failSum(int item,int form,int frageForm){
|
||||||
|
return failsSums[item][form][frageForm];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fails(int item,int form,int frageForm,int falshe){
|
||||||
|
return fails[item][form][frageForm][falshe];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int[] failSums(){
|
||||||
|
return failSums;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] failSums(int item){
|
||||||
|
return failsSum[item];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] failSums(int item,int form){
|
||||||
|
return failsSums[item][form];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] failSums(int item,int form,int falsheForm){
|
||||||
|
return fails[item][form][falsheForm];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAFail(int item, int form,int frageForm, int falshe) {
|
||||||
|
this.fails[item][form][frageForm][falshe]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.bernard.mcqinator.api.fragenStats;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 04/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class QuizStat<Q extends Quiz> {
|
||||||
|
|
||||||
|
private static final Pattern QUIZ_FILE_PATTERN = Pattern.compile("^stats_([0-9]+).bernard$");
|
||||||
|
|
||||||
|
public static QuizStat createStat(Class<? extends QuizStat> statClass,Quiz q){
|
||||||
|
try {
|
||||||
|
QuizStat stat = statClass.newInstance();
|
||||||
|
checkedGenDefault(stat,q);
|
||||||
|
return stat;
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
Log.e("StatCreator","The class "+statClass.getName()+" is not instatiable ... try to add a 'no arg' constructor",e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.e("StatCreator","The class "+statClass.getName()+" is not reachable ... try to make it public",e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static void checkedGenDefault(QuizStat s,Quiz q){
|
||||||
|
s.genDefault(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void genDefault(Q q);
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Getters / Setters ////////////
|
||||||
|
|
||||||
|
//////////// File Methods ////////////
|
||||||
|
|
||||||
|
public abstract void read(DataInputStream dis) throws IOException;
|
||||||
|
|
||||||
|
public abstract void write(DataOutputStream dos) throws IOException;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package com.bernard.mcqinator.api.quiz;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 17/04/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DEVerbenQuiz extends FormQuiz{
|
||||||
|
|
||||||
|
private static final int[] formNamesIDs = {R.string.infinitif,R.string.prasens2,R.string.prasens3,R.string.prateritum2,R.string.prateritum3,R.string.partizipPerfekt};
|
||||||
|
|
||||||
|
public static final int AUX_HABEN = 0b0,AUX_SEIN = 0b1;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBlocFrageText(int itemID, int formID, int fformID, BlocData frageData, Context context) {
|
||||||
|
return context.getResources().getString(R.string.wasIstDasVon,context.getResources().getString(formNamesIDs[getItems()[itemID].getForms()[formID].getFormID()]),getItems()[itemID].getForms()[fformID].getRichtig(),context.getResources().getString(formNamesIDs[getItems()[itemID].getForms()[fformID].getFormID()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEditActivityLayoutID() {
|
||||||
|
return R.layout.activity_edit_quiz_deverben;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEditItemActivityFormLayoutID() {
|
||||||
|
return R.layout.edit_form_quiz_item_form;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEditItemActivityFalseLayoutID() {
|
||||||
|
return R.layout.edit_form_quiz_item_false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEditItemActivityLayoutID() {
|
||||||
|
return R.layout.edit_form_quiz_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFormCount() {
|
||||||
|
return formNamesIDs.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected View getEditQuizItemView(Item item, int position, View convertView, ViewGroup parent,Context c) {
|
||||||
|
View group = (convertView == null)?LayoutInflater.from(c).inflate(R.layout.verbe_row_layout,parent,false):(ViewGroup)convertView;
|
||||||
|
((TextView)group.findViewById(R.id.verbeInfinitifText)).setText(item.getForms()[0].getRichtig());
|
||||||
|
((TextView)group.findViewById(R.id.verbeOthersText)).setText(item.getForms()[1].getRichtig()+item.getForms()[3].getRichtig()+item.getForms()[5].getRichtig());
|
||||||
|
int ram = 0;
|
||||||
|
for (Item.Form f : item.getForms())
|
||||||
|
ram+=f.getFalshe().length + 1;
|
||||||
|
((TextView)group.findViewById(R.id.verbeInfinitifText)).setText(c.getResources().getQuantityString(R.plurals.worteCount,ram,ram));
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFormNameStringId(int pos) {
|
||||||
|
return formNamesIDs[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VerbeAdapter extends BaseAdapter{
|
||||||
|
final Context ctx;
|
||||||
|
|
||||||
|
public VerbeAdapter(Context ctx) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return getItems().length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item getItem(int position) {
|
||||||
|
return getItems()[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View layout = (convertView != null)?convertView: LayoutInflater.from(ctx).inflate(R.layout.verbe_row_layout,parent,false);
|
||||||
|
TextView infinitif = layout.findViewById(R.id.verbeInfinitifText);
|
||||||
|
TextView others = layout.findViewById(R.id.verbeOthersText);
|
||||||
|
TextView worteCount = layout.findViewById(R.id.verbeWorteCountText);
|
||||||
|
|
||||||
|
Item i = this.getItem(position);
|
||||||
|
infinitif.setText(i.getForms()[0].getRichtig());
|
||||||
|
others.setText(i.getForms()[3].getRichtig() + "," + i.getForms()[5].getRichtig() + "," + i.getForms()[6].getRichtig());
|
||||||
|
int wC = i.getForms()[0].getFalshe().length + i.getForms()[1].getFalshe().length + i.getForms()[2].getFalshe().length + i.getForms()[3].getFalshe().length + i.getForms()[4].getFalshe().length + i.getForms()[5].getFalshe().length + i.getForms()[6].getFalshe().length;
|
||||||
|
worteCount.setText(ctx.getResources().getQuantityString(R.plurals.worteCount,wC,wC));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
456
app/src/main/java/com/bernard/mcqinator/api/quiz/FormQuiz.java
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
package com.bernard.mcqinator.api.quiz;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.IdentifiedQuiz;
|
||||||
|
import com.bernard.mcqinator.api.frageable.BlocFrageable;
|
||||||
|
import com.bernard.mcqinator.api.fragen.BlocFrage;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.FormQuizStat;
|
||||||
|
import com.bernard.mcqinator.inutil.ArrayInutil;
|
||||||
|
import com.bernard.mcqinator.inutil.NumberInutil;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static com.bernard.mcqinator.inutil.ArrayInutil.asize;
|
||||||
|
import static com.bernard.mcqinator.inutil.ArrayInutil.count;
|
||||||
|
import static com.bernard.mcqinator.inutil.ArrayInutil.range;
|
||||||
|
import static com.bernard.mcqinator.inutil.ArrayInutil.toObjectArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 28/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class FormQuiz extends Quiz implements BlocFrageable<FormQuizStat,FormQuiz.Identifier> {
|
||||||
|
|
||||||
|
private FormQuiz.Item[] items;
|
||||||
|
private String[] idS;
|
||||||
|
|
||||||
|
//TODO make forms no-declareable (withs forms IDs)
|
||||||
|
|
||||||
|
//////////// BlocFrage ////////////
|
||||||
|
@Override
|
||||||
|
public IdentifiedQuiz<BlocFrage,Identifier> genFragen(FormQuizStat stat, BlocData frageData, Context context, ProgressDialog wait) {
|
||||||
|
|
||||||
|
// Initialisation des variables
|
||||||
|
Random r = new Random();
|
||||||
|
|
||||||
|
// Correction des potentielles erreurs du quiz
|
||||||
|
if(items.length <= 0)
|
||||||
|
throw new IllegalStateException("There is no frage in this quiz !");//TODO implement special error, that is toasted to the user
|
||||||
|
|
||||||
|
// Selection des items
|
||||||
|
List<Integer> itemsPos = asize(range(0,items.length),frageData.length,toObjectArray(stat.failSums()),stat.failSum(),r);
|
||||||
|
Map<Integer,Integer> itemsPosAndCount = count(itemsPos);
|
||||||
|
|
||||||
|
//Selection de la form à trouver
|
||||||
|
|
||||||
|
Map<Integer[],Integer> formsPosAndCount = new HashMap<>();
|
||||||
|
|
||||||
|
for(Map.Entry<Integer,Integer> e : itemsPosAndCount.entrySet()){
|
||||||
|
Integer[][] formsIDs = new Integer[items[e.getKey()].forms.length][2];
|
||||||
|
for (int i = 0; i < formsIDs.length; i++)
|
||||||
|
formsIDs[i] = new Integer[]{e.getKey(),i};
|
||||||
|
Map<Integer[],Integer> formPosAndCount = count(asize(formsIDs,e.getValue(),toObjectArray(stat.failSums(e.getKey())),stat.failSum(e.getKey()),r));
|
||||||
|
formsPosAndCount.putAll(formPosAndCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selection de la form question
|
||||||
|
Map<Integer[],Integer> fformsPosAndCount = new HashMap<>();
|
||||||
|
|
||||||
|
for(Map.Entry<Integer[],Integer> e : formsPosAndCount.entrySet()){
|
||||||
|
int itemID = e.getKey()[0];
|
||||||
|
int formID = e.getKey()[1];
|
||||||
|
List<Integer[]> fformsIDs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < items[itemID].forms.length - 1; i++)
|
||||||
|
fformsIDs.add(new Integer[]{itemID,formID, i});
|
||||||
|
Log.v("R","Rutabaga" + itemID);
|
||||||
|
Map<Integer[],Integer> fformPosAndCount = count(asize(fformsIDs,e.getValue(),toObjectArray(stat.failSums(itemID,formID)),stat.failSum(itemID,formID),r));
|
||||||
|
Log.v("R","Salsifi");
|
||||||
|
fformsPosAndCount.putAll(fformPosAndCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selection des mauvaises réponces
|
||||||
|
List<BlocFrage> fragen = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
for(Map.Entry<Integer[],Integer> e : fformsPosAndCount.entrySet()){
|
||||||
|
int itemID = e.getKey()[0];
|
||||||
|
int formID = e.getKey()[1];
|
||||||
|
int fformID = e.getKey()[2];
|
||||||
|
String frageText = getBlocFrageText(itemID,formID, NumberInutil.exclude(fformID,formID),frageData,context);
|
||||||
|
Item.Form form = items[itemID].getForms()[formID];
|
||||||
|
String richtigAntwort = form.getRichtig();
|
||||||
|
List<Integer[]> falsheIDs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < items[itemID].forms[formID].getFalshe().length; i++)
|
||||||
|
falsheIDs.add(new Integer[]{itemID,formID,fformID,i});
|
||||||
|
List<Integer[]> falshPoz = asize(falsheIDs,e.getValue() * (frageData.blockNumber - 1),toObjectArray(stat.failSums(itemID,formID,fformID)),stat.failSum(itemID,formID,fformID),r);
|
||||||
|
for (int i = 0; i < falshPoz.size(); i+=(frageData.blockNumber - 1)) {
|
||||||
|
List<Integer[]> falsheBloc = falshPoz.subList(i,i+(frageData.blockNumber - 1));
|
||||||
|
String[] falsheBlocArray = new String[falsheBloc.size()];
|
||||||
|
for (int j = 0; j < falsheBlocArray.length; j++)
|
||||||
|
falsheBlocArray[j] = form.getFalshe()[falsheBloc.get(j)[3]];
|
||||||
|
|
||||||
|
fragen.add(new BlocFrage(frageText,richtigAntwort,falsheBlocArray));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer[]> idsFragen = new ArrayList<>(fformsPosAndCount.keySet());
|
||||||
|
List<Integer> poss = Arrays.asList(ArrayInutil.range(0,idsFragen.size()));
|
||||||
|
Collections.shuffle(poss,r);
|
||||||
|
|
||||||
|
Integer[][] shuffledIdsFragen = new Integer[idsFragen.size()][];
|
||||||
|
BlocFrage[] shuffledFragenArray = new BlocFrage[fragen.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i < poss.size(); i++) {
|
||||||
|
shuffledIdsFragen[i] = idsFragen.get(poss.get(i));
|
||||||
|
shuffledFragenArray[i] = fragen.get(poss.get(i));
|
||||||
|
}
|
||||||
|
Log.v("BlocFrageGenerator","Done !");
|
||||||
|
|
||||||
|
return new IdentifiedQuiz<>(shuffledFragenArray,new Identifier(ArrayInutil.toPrimitiveArray(shuffledIdsFragen)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getBlocFrageText(int itemID, int formID, int fformID, BlocData frageData, Context context);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FormQuizStat updateStats(FormQuizStat oldStats, List<BlocFrage.Reply> replies,FormQuiz.Identifier identifier) {
|
||||||
|
if(replies.size() != identifier.formIndexes.length)throw new IllegalArgumentException("The identifier dont match with the number of replies recieved");
|
||||||
|
for (int i = 0; i < replies.size(); i++) {
|
||||||
|
int itemID = identifier.formIndexes[i][0];
|
||||||
|
int formID = identifier.formIndexes[i][1];
|
||||||
|
int fformID = identifier.formIndexes[i][2];
|
||||||
|
String answered = replies.get(i).getAnswered();
|
||||||
|
if(items[itemID].getForms()[formID].getRichtig().equals(answered))
|
||||||
|
continue;
|
||||||
|
int falsheAntwortID = ArrayInutil.indexOf(items[itemID].getForms()[formID].getFalshe(),answered);
|
||||||
|
oldStats.addAFail(itemID,formID,fformID,falsheAntwortID);
|
||||||
|
}
|
||||||
|
return oldStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void genDefault() {
|
||||||
|
items = new FormQuiz.Item[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Getters / Setters ////////////
|
||||||
|
|
||||||
|
//TODO set setters for editactivities
|
||||||
|
|
||||||
|
public void addItem(Item i){
|
||||||
|
Item[] litem = new Item[items.length+1];
|
||||||
|
System.arraycopy(items,0,litem,0,items.length);
|
||||||
|
litem[litem.length-1] = i;
|
||||||
|
items = litem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(int pos,Item i){
|
||||||
|
items[pos] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormQuiz.Item[] getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormQuiz.Item getItem(int pos) {
|
||||||
|
return items[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Customization methods ////////////
|
||||||
|
|
||||||
|
//TODO add more abstract methods for a full customisation
|
||||||
|
|
||||||
|
public abstract int getEditActivityLayoutID();
|
||||||
|
|
||||||
|
public abstract int getEditItemActivityFormLayoutID();
|
||||||
|
|
||||||
|
public abstract int getEditItemActivityFalseLayoutID();
|
||||||
|
|
||||||
|
public abstract int getEditItemActivityLayoutID();
|
||||||
|
|
||||||
|
protected abstract View getEditQuizItemView(Item item, int position, View convertView, ViewGroup parent, Context c);
|
||||||
|
|
||||||
|
public abstract int getFormNameStringId(int pos);
|
||||||
|
|
||||||
|
public abstract int getFormCount();
|
||||||
|
|
||||||
|
|
||||||
|
//////////// File Methods ////////////
|
||||||
|
|
||||||
|
public void write(DataOutputStream dos) throws IOException{
|
||||||
|
dos.writeInt(items.length);
|
||||||
|
for (Item i : items)
|
||||||
|
i.write(dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(DataInputStream dis) throws IOException{
|
||||||
|
items = new Item[dis.readInt()];
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
items[i] = new Item();
|
||||||
|
items[i].read(dis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Internal Classes ////////////
|
||||||
|
|
||||||
|
//TODO implement all
|
||||||
|
//TODO remove parcelable and serialiable if not used
|
||||||
|
public static class Item implements Parcelable,Serializable {
|
||||||
|
|
||||||
|
Form[] forms;
|
||||||
|
|
||||||
|
public Item(Form[] forms) {
|
||||||
|
this.forms = forms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item() {} // For serialization
|
||||||
|
|
||||||
|
//////////// Getters / Setters ////////////
|
||||||
|
|
||||||
|
public Form[] getForms() {
|
||||||
|
return forms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForms(Form[] forms) {
|
||||||
|
this.forms = forms;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Parcelable ////////////
|
||||||
|
|
||||||
|
protected Item(Parcel in) {
|
||||||
|
forms = in.createTypedArray(Form.CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<Item> CREATOR = new Creator<Item>() {
|
||||||
|
@Override
|
||||||
|
public Item createFromParcel(Parcel in) {
|
||||||
|
return new Item(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item[] newArray(int size) {
|
||||||
|
return new Item[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeTypedArray(forms,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// File Methods ////////////
|
||||||
|
|
||||||
|
public void write(DataOutputStream dos) throws IOException{
|
||||||
|
dos.writeInt(forms.length);
|
||||||
|
for (Form f : forms)
|
||||||
|
f.write(dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(DataInputStream dis) throws IOException{
|
||||||
|
forms = new Form[dis.readInt()];
|
||||||
|
for (int i = 0; i < forms.length; i++) {
|
||||||
|
forms[i] = new Form();
|
||||||
|
forms[i].read(dis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Internal Classes ////////////
|
||||||
|
|
||||||
|
public static class Form implements Parcelable,Serializable {
|
||||||
|
|
||||||
|
String richtig;
|
||||||
|
String[] falshe;
|
||||||
|
int formID;
|
||||||
|
|
||||||
|
public Form(int formID,String richtig, String... falshe) {
|
||||||
|
this.richtig = richtig;
|
||||||
|
this.falshe = falshe;
|
||||||
|
this.formID = formID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Form(Parcel in) {
|
||||||
|
formID = in.readInt();
|
||||||
|
richtig = in.readString();
|
||||||
|
falshe = in.createStringArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Form() {} //For serialization
|
||||||
|
|
||||||
|
//////////// Getters / Setters ////////////
|
||||||
|
|
||||||
|
public String getRichtig() {
|
||||||
|
return richtig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getFalshe() {
|
||||||
|
return falshe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFormID() {
|
||||||
|
return formID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////// File Methods ////////////
|
||||||
|
|
||||||
|
public void write(DataOutputStream dos) throws IOException{
|
||||||
|
dos.writeInt(formID);
|
||||||
|
if(richtig == null) {
|
||||||
|
dos.writeInt(0);
|
||||||
|
}else{
|
||||||
|
dos.writeInt(richtig.getBytes().length);
|
||||||
|
dos.write(richtig.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
dos.writeInt(falshe.length);
|
||||||
|
for(String f : falshe){
|
||||||
|
if(f == null){
|
||||||
|
dos.writeInt(0);
|
||||||
|
}else {
|
||||||
|
dos.writeInt(f.getBytes().length);
|
||||||
|
dos.write(f.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(DataInputStream dis) throws IOException{
|
||||||
|
formID = dis.readInt();
|
||||||
|
byte[] richtigBytes = new byte[dis.readInt()];
|
||||||
|
int read = dis.read(richtigBytes);
|
||||||
|
if(read != richtigBytes.length)throw new IOException("Fichier invalide ... la taille annoncée du string richtig n'est pas satisfaite ");
|
||||||
|
richtig = new String(richtigBytes);
|
||||||
|
falshe = new String[dis.readInt()];
|
||||||
|
for (int i = 0; i < falshe.length; i++) {
|
||||||
|
byte[] falshBytes = new byte[dis.readInt()];
|
||||||
|
read = dis.read(falshBytes);
|
||||||
|
if(read != falshBytes.length)throw new IOException("Fichier invalide ... la taille annoncée du string falche n°"+i+" n'est pas satisfaite ");
|
||||||
|
falshe[i] = new String(falshBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Parcelable ////////////
|
||||||
|
|
||||||
|
public static final Creator<Form> CREATOR = new Creator<Form>() {
|
||||||
|
@Override
|
||||||
|
public Form createFromParcel(Parcel in) {
|
||||||
|
return new Form(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Form[] newArray(int size) {
|
||||||
|
return new Form[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeInt(formID);
|
||||||
|
dest.writeString(richtig);
|
||||||
|
dest.writeStringArray(falshe);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////// Misc ////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Form{" +
|
||||||
|
"richtig='" + richtig + '\'' +
|
||||||
|
", falshe=" + Arrays.toString(falshe) +
|
||||||
|
", formID=" + formID +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Misc ////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Item{" +
|
||||||
|
"forms=" + Arrays.toString(forms) +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Identifier extends Frage.Identifier{
|
||||||
|
/*
|
||||||
|
Array of type {[ItemPos,FormPos,FformPos],[ItemPos,FormPos,FformPos],...}
|
||||||
|
*/
|
||||||
|
final int[][] formIndexes;
|
||||||
|
|
||||||
|
|
||||||
|
public Identifier(int[][] formIndexes) {
|
||||||
|
this.formIndexes = formIndexes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//LATER move
|
||||||
|
public class ItemAdapter extends BaseAdapter{
|
||||||
|
|
||||||
|
final Context c;
|
||||||
|
|
||||||
|
public ItemAdapter(Context c) {
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return items.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item getItem(int position) {
|
||||||
|
return items[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
return FormQuiz.this.getEditQuizItemView(items[position], position, convertView, parent,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Misc ////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DEVerbenQuiz (" + Arrays.deepToString(items) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/src/main/java/com/bernard/mcqinator/api/quiz/Quiz.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package com.bernard.mcqinator.api.quiz;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by samy on 14/04/17.
|
||||||
|
* @author Mysaa
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class Quiz<S extends QuizStat> implements Serializable {
|
||||||
|
|
||||||
|
public abstract void genDefault();
|
||||||
|
|
||||||
|
public abstract void write(DataOutputStream fos) throws IOException;
|
||||||
|
|
||||||
|
public abstract void read(DataInputStream fin) throws IOException;
|
||||||
|
}
|
||||||
@ -0,0 +1,301 @@
|
|||||||
|
package com.bernard.mcqinator.controller;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
import com.bernard.mcqinator.inutil.NumberInutil;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 22/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class FileManager {
|
||||||
|
|
||||||
|
private static final Random fileNamesRandom = new Random();
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Consts ////////////
|
||||||
|
|
||||||
|
public static final byte[] appBernardKey = {0b00100010,0b01001001};
|
||||||
|
public static final byte[] appBernardKeyStat = {0b00100011,0b01001000};
|
||||||
|
public static final byte[] bernardSignature = {0b00011001,0b01101101};
|
||||||
|
|
||||||
|
|
||||||
|
//////////// QuizStat ////////////
|
||||||
|
|
||||||
|
public static String statFilename(long fileID){
|
||||||
|
return "stat_"+ NumberInutil.toUnsignedString(fileID)+".bernard";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String statFilename(QuizMetadata quiz){
|
||||||
|
return statFilename(quiz.getFileID());
|
||||||
|
}
|
||||||
|
|
||||||
|
////// Save //////
|
||||||
|
|
||||||
|
public static void saveStat(QuizMetadata quiz,QuizStat stat,Context ctx){
|
||||||
|
try {
|
||||||
|
ctx.deleteFile(statFilename(quiz));
|
||||||
|
saveStatAsFile(stat,quiz,new DataOutputStream(ctx.openFileOutput(statFilename(quiz),Context.MODE_PRIVATE)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("FileManager","Can't save the quiz stat " + stat,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveStatAsFile(QuizStat stat,QuizMetadata meta,DataOutputStream dos,boolean closeDatautputStream) throws IOException {
|
||||||
|
//LATER implement bernard API
|
||||||
|
//Writing Bernard signature
|
||||||
|
dos.write(FileManager.bernardSignature);
|
||||||
|
|
||||||
|
//Writing Bernard key
|
||||||
|
dos.write(FileManager.appBernardKeyStat);
|
||||||
|
|
||||||
|
//Writing fileType
|
||||||
|
dos.writeInt(meta.getType().getId());
|
||||||
|
|
||||||
|
//Writing quiz
|
||||||
|
stat.write(dos);
|
||||||
|
|
||||||
|
if(closeDatautputStream)dos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveStatAsFile(QuizStat stat,QuizMetadata meta,DataOutputStream dos) throws IOException {
|
||||||
|
saveStatAsFile(stat,meta,dos,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
////// Get //////
|
||||||
|
|
||||||
|
public static QuizStat getStat(QuizMetadata quiz, Context ctx){
|
||||||
|
try {
|
||||||
|
return getFromFile(new DataInputStream(ctx.openFileInput(statFilename(quiz.getFileID()))));
|
||||||
|
}catch (IOException e) {
|
||||||
|
Log.e("FileManager","Cannot read QuizStat of quiz " + quiz,e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static QuizStat getFromFile(DataInputStream din) throws IOException {
|
||||||
|
|
||||||
|
//LATER implement bernard API
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
//Assert bernard signature
|
||||||
|
byte[] bernardSignature = new byte[2];
|
||||||
|
readBytes = din.read(bernardSignature);
|
||||||
|
if(readBytes != 2 || bernardSignature[0] != FileManager.bernardSignature[0] || bernardSignature[1] != FileManager.bernardSignature[1]){
|
||||||
|
din.close();
|
||||||
|
throw new IOException("Corrupted quizStat : wrong bernard signature");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte[] bernardType = new byte[2];
|
||||||
|
readBytes = din.read(bernardType);
|
||||||
|
if(readBytes != 2 || bernardType[0] != FileManager.appBernardKeyStat[0] || bernardType[1] != FileManager.appBernardKeyStat[1]) {
|
||||||
|
din.close();
|
||||||
|
throw new IOException("Corrupted quizStat : wrong QuizStat key");
|
||||||
|
}
|
||||||
|
|
||||||
|
int quizTypeNum = din.readInt();
|
||||||
|
QuizMetadata.Type type = QuizMetadata.Type.getTypeFromID(quizTypeNum);
|
||||||
|
if(type == null){
|
||||||
|
din.close();
|
||||||
|
throw new IOException("Corrupted quizStat : unknown QuizType ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
QuizStat actual;
|
||||||
|
try{
|
||||||
|
actual = type.getQuizStatClass().newInstance();
|
||||||
|
actual.read(din);
|
||||||
|
Log.v("FileManager","QuizStat successfully read !");
|
||||||
|
}catch(Exception e) {
|
||||||
|
din.close();
|
||||||
|
throw new IOException("Corrupted quizStat : unreadable content", e);
|
||||||
|
}
|
||||||
|
din.close();
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Quiz ////////////
|
||||||
|
|
||||||
|
private static String quizFilename(long fileID){
|
||||||
|
return "quiz_"+ NumberInutil.toUnsignedString(fileID)+".bernard";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String quizFilename(QuizMetadata quiz){
|
||||||
|
return quizFilename(quiz.getFileID());
|
||||||
|
}
|
||||||
|
|
||||||
|
////// Save //////
|
||||||
|
|
||||||
|
public static void saveQuiz(QuizMetadata meta,Quiz q,Context ctx){
|
||||||
|
try {
|
||||||
|
ctx.deleteFile(quizFilename(meta));
|
||||||
|
saveQuizAsFile(new DataOutputStream(ctx.openFileOutput(quizFilename(meta),Context.MODE_PRIVATE)), meta, q);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("FileManager","Cant save the quiz " + q + "at" + meta,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void saveQuizAsFile(DataOutputStream dos,QuizMetadata meta, Quiz q,boolean justPayload,boolean closeDataOutputStream) throws IOException {
|
||||||
|
|
||||||
|
if(!justPayload) {
|
||||||
|
//Writing Bernard signature
|
||||||
|
dos.write(FileManager.bernardSignature);
|
||||||
|
|
||||||
|
//Writing Bernard key
|
||||||
|
dos.write(FileManager.appBernardKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Writing quizType key
|
||||||
|
dos.writeInt(meta.getType().getId());
|
||||||
|
|
||||||
|
//Writing quiz
|
||||||
|
q.write(dos);
|
||||||
|
|
||||||
|
if(closeDataOutputStream)dos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void saveQuizAsFile(DataOutputStream dos,QuizMetadata meta, Quiz q) throws IOException {
|
||||||
|
saveQuizAsFile(dos,meta,q,false,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
////// Get //////
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static Quiz getQuizFromFile(DataInputStream dis,boolean justPayload) throws IOException {
|
||||||
|
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
if(!justPayload) {
|
||||||
|
|
||||||
|
//Assert bernard signature
|
||||||
|
byte[] bernardSignature = new byte[2];
|
||||||
|
readBytes = dis.read(bernardSignature);
|
||||||
|
if(readBytes != 2 || bernardSignature[0] != FileManager.bernardSignature[0] || bernardSignature[1] != FileManager.bernardSignature[1]){
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Corrupted quiz : wrong bernard signature");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte[] bernardType = new byte[2];
|
||||||
|
readBytes = dis.read(bernardType);
|
||||||
|
if(readBytes != 2 || bernardType[0] != FileManager.appBernardKey[0] || bernardType[1] != FileManager.appBernardKey[1]) {
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Corrupted quiz : wrong Quiz key");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int quizTypeNum = dis.readInt();
|
||||||
|
QuizMetadata.Type type = QuizMetadata.Type.getTypeFromID(quizTypeNum);
|
||||||
|
if(type == null){
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Unknown quiz type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Quiz actual;
|
||||||
|
try{
|
||||||
|
actual = type.getQuizClass().newInstance();
|
||||||
|
actual.read(dis);
|
||||||
|
Log.v("FileManager","Quiz successfully read");
|
||||||
|
}catch(Exception e){
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Corrupted quiz : wrong content",e);
|
||||||
|
}
|
||||||
|
dis.close();
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Quiz getQuizFromFile(DataInputStream dis) throws IOException {
|
||||||
|
return getQuizFromFile(dis,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Quiz getQuiz(QuizMetadata meta,Context ctx) throws IOException {
|
||||||
|
try {
|
||||||
|
return getQuizFromFile(new DataInputStream(ctx.openFileInput(quizFilename(meta.getFileID()))));
|
||||||
|
}catch (IOException e) {
|
||||||
|
Log.e("FileManager","Cannot read Quiz with meta " + meta,e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
////// Import / Export //////
|
||||||
|
|
||||||
|
public static void exportQuizToFile(QuizMetadata meta,Context ctx,File f){
|
||||||
|
try {
|
||||||
|
//LATER implement Bernard API
|
||||||
|
DataOutputStream dos = new DataOutputStream(new FileOutputStream(f));
|
||||||
|
long temp = meta.getFileID();
|
||||||
|
meta.setFileID(-1);
|
||||||
|
meta.write(dos);
|
||||||
|
meta.setFileID(temp);
|
||||||
|
saveQuizAsFile(dos,meta,getQuiz(meta,ctx),true,true);//Do the dos.close()
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static QuizMetadata importQuizFromFile(Context ctx,File f) throws IOException {
|
||||||
|
DataInputStream dis = new DataInputStream(new FileInputStream(f));
|
||||||
|
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
byte[] bernardSignature = new byte[2];
|
||||||
|
readBytes = dis.read(bernardSignature);
|
||||||
|
if(readBytes != 2 || bernardSignature[0] != FileManager.bernardSignature[0] || bernardSignature[1] != FileManager.bernardSignature[1]){
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Corrupted quiz : wrong bernard sign");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bernardType = new byte[2];
|
||||||
|
readBytes = dis.read(bernardType);
|
||||||
|
if(readBytes != 2 || bernardType[0] != FileManager.appBernardKey[0] || bernardType[1] != FileManager.appBernardKey[1]) {
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("Corrupted quiz : wrong app sign");
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO add special key to QUIZ_WITH_METADATA
|
||||||
|
|
||||||
|
QuizMetadata toImport = new QuizMetadata();
|
||||||
|
toImport.read(dis);
|
||||||
|
|
||||||
|
Quiz q = getQuizFromFile(dis,true);
|
||||||
|
|
||||||
|
QuizMetadata newMetadata = QuizMetadataManager.createQuiz(ctx,toImport.getName(),toImport.getAuthor(),toImport.getType(),toImport.isEditable());
|
||||||
|
saveQuiz(newMetadata,q,ctx);
|
||||||
|
return newMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Global ////////////
|
||||||
|
|
||||||
|
public static long getAvalivableFileID(Context ctx){
|
||||||
|
long fileID;
|
||||||
|
do{
|
||||||
|
fileID = fileNamesRandom.nextLong();
|
||||||
|
}while(new File(ctx.getFilesDir(),quizFilename(fileID)).exists() || new File(ctx.getFilesDir(),statFilename(fileID)).exists());
|
||||||
|
return fileID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean delete(QuizMetadata m,Context c) {
|
||||||
|
return c.deleteFile(quizFilename(m)) && !c.deleteFile(statFilename(m)) && QuizMetadataManager.delete(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,187 @@
|
|||||||
|
package com.bernard.mcqinator.controller;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
import com.bernard.mcqinator.inutil.ArrayInutil;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 23/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class QuizMetadataManager {
|
||||||
|
|
||||||
|
private static List<QuizMetadata> savedQuizs;
|
||||||
|
|
||||||
|
|
||||||
|
private static final String SAVED_METADATA_FILENAME = "savedQuizz.bernard";
|
||||||
|
|
||||||
|
public static void saveSavedQuizList(Context ctx){
|
||||||
|
DataOutputStream dos = null;
|
||||||
|
try {
|
||||||
|
//LATER implement Bernard API
|
||||||
|
dos = new DataOutputStream(ctx.openFileOutput(SAVED_METADATA_FILENAME, Context.MODE_PRIVATE));
|
||||||
|
dos.write(FileManager.bernardSignature);
|
||||||
|
dos.write(FileManager.appBernardKey);
|
||||||
|
dos.writeInt(-1);// Metadata file identifier
|
||||||
|
dos.writeInt(savedQuizs.size());
|
||||||
|
|
||||||
|
for (QuizMetadata m : savedQuizs)
|
||||||
|
m.write(dos);
|
||||||
|
|
||||||
|
Log.v("QuizMetadataManager","Quiz metadatas saved !");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("QuizMetadataManager","Cannot save quiz metadata list",e);
|
||||||
|
}finally {
|
||||||
|
if(dos != null)
|
||||||
|
try {
|
||||||
|
dos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("QuizMetadataManager","Cannot close the QuizMetadataSaver's DataOutputStream",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void retieveSavedQuizList(Context ctx) {
|
||||||
|
savedQuizs = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
//LATER implement bernard API
|
||||||
|
if(!ArrayInutil.inArray(SAVED_METADATA_FILENAME,ctx.fileList())){
|
||||||
|
Log.v("QuizMetadataManager","Cannot find the savedMetadata file , creating one");
|
||||||
|
DataOutputStream dos = new DataOutputStream(ctx.openFileOutput(SAVED_METADATA_FILENAME,Context.MODE_PRIVATE));
|
||||||
|
dos.write(FileManager.bernardSignature);
|
||||||
|
dos.write(FileManager.appBernardKey);
|
||||||
|
dos.writeInt(-1);// Metadata file identifier
|
||||||
|
dos.writeInt(0);// Stored QuizMetadata count (no metadata stored)
|
||||||
|
dos.close();
|
||||||
|
Log.v("QuizMetadataManager","New metadata file created !");
|
||||||
|
}
|
||||||
|
DataInputStream dis = new DataInputStream(ctx.openFileInput(SAVED_METADATA_FILENAME));
|
||||||
|
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
byte[] bernardSignature = new byte[2];
|
||||||
|
readBytes = dis.read(bernardSignature);
|
||||||
|
if (readBytes != 2 || bernardSignature[0] != FileManager.bernardSignature[0] || bernardSignature[1] != FileManager.bernardSignature[1]) {
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("The QuizMetatatas file has no bernard sign !");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bernardType = new byte[2];
|
||||||
|
readBytes = dis.read(bernardType);
|
||||||
|
if (readBytes != 2 ||bernardType[0] != FileManager.appBernardKey[0] || bernardType[1] != FileManager.appBernardKey[1]) {
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("The QuizMetatatas file has no app sign !");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dis.readInt() != -1) {
|
||||||
|
dis.close();
|
||||||
|
throw new IOException("The QuizMetatatas file has no quizmetadata file sign !");
|
||||||
|
}
|
||||||
|
|
||||||
|
int quizCount = dis.readInt();
|
||||||
|
|
||||||
|
for (int i = 0; i < quizCount; i++) {
|
||||||
|
savedQuizs.add(QuizMetadata.class.newInstance());
|
||||||
|
savedQuizs.get(i).read(dis);
|
||||||
|
}
|
||||||
|
dis.close();
|
||||||
|
Log.v("QuizMetadataManager","Successfuly read quiz metadata file");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("QuizMetadataManager", "Corrupted QuizMetadata file !",e);
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
Log.e("QuizMetadataManager","Cannot read quizmetadata file : cannot instantiate QuizMetadata",e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.e("QuizMetadataManager","Cannot read quizmetadata file : cannot acess QuizMetadata constructor",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Get ////////////
|
||||||
|
|
||||||
|
public static List<QuizMetadata> getAll(Context ctx){
|
||||||
|
if(savedQuizs == null)
|
||||||
|
retieveSavedQuizList(ctx);
|
||||||
|
return new ArrayList<>(savedQuizs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<QuizMetadata> getAllQuiz(Context ctx,boolean editable){
|
||||||
|
if(savedQuizs == null)
|
||||||
|
retieveSavedQuizList(ctx);
|
||||||
|
List<QuizMetadata> toReturn = new ArrayList<>();
|
||||||
|
for (QuizMetadata metadata : savedQuizs)
|
||||||
|
if(metadata.isEditable() == editable)toReturn.add(metadata);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<QuizMetadata> getAllQuiz(Context ctx,QuizMetadata.Type t){
|
||||||
|
if(savedQuizs == null)
|
||||||
|
retieveSavedQuizList(ctx);
|
||||||
|
List<QuizMetadata> toReturn = new ArrayList<>();
|
||||||
|
for (QuizMetadata metadata : savedQuizs)
|
||||||
|
if(metadata.getType().equals(t))toReturn.add(metadata);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static QuizMetadata getQuiz(Context ctx,long fileID){
|
||||||
|
if(savedQuizs == null)
|
||||||
|
retieveSavedQuizList(ctx);
|
||||||
|
for (QuizMetadata metadata : savedQuizs)
|
||||||
|
if(metadata.getFileID() == fileID)return metadata;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Delete ////////////
|
||||||
|
|
||||||
|
public static boolean delete(QuizMetadata m) {
|
||||||
|
for(QuizMetadata meta : savedQuizs)
|
||||||
|
if(meta.getFileID() == m.getFileID())
|
||||||
|
return savedQuizs.remove(meta);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Create ////////////
|
||||||
|
|
||||||
|
public static QuizMetadata createQuiz(Context ctx, String name, String author, QuizMetadata.Type type, boolean editable){
|
||||||
|
try {
|
||||||
|
Quiz q = type.getQuizClass().newInstance();
|
||||||
|
q.genDefault();
|
||||||
|
QuizMetadata meta = new QuizMetadata(name,author,FileManager.getAvalivableFileID(ctx),type,editable);
|
||||||
|
FileManager.saveQuiz(meta,q,ctx);
|
||||||
|
savedQuizs.add(meta);
|
||||||
|
return meta;
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
Log.e("QuizMetadataManager","Error instantiating some class ... do you have all the constructors needed ?",e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.e("QuizMetadataManager","Error instantiating some class ... are the constructors public if they have to be so ?",e);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Cannot create the quiz ... watch earlier in the log for more informations");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static QuizMetadata createQuiz(Context ctx,String name, String author, boolean editable, QuizMetadata parent){
|
||||||
|
try {
|
||||||
|
Quiz parentQuiz = FileManager.getQuiz(parent,ctx);
|
||||||
|
QuizMetadata nMetadata = new QuizMetadata(name,author,FileManager.getAvalivableFileID(ctx),parent.getType(),editable);
|
||||||
|
FileManager.saveQuiz(nMetadata,parentQuiz,ctx);
|
||||||
|
savedQuizs.add(nMetadata);
|
||||||
|
return nMetadata;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("QuizMetadataManager","IO error when trying to create the quizz",e);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Cannot create the quiz ... watch earlier in the log for more informations");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
158
app/src/main/java/com/bernard/mcqinator/inutil/ArrayInutil.java
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
package com.bernard.mcqinator.inutil;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 22/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ArrayInutil {
|
||||||
|
|
||||||
|
public static <X> List<X> asize(List<X> items, int length, Integer[] failSumsArray, int failSum, Random r){
|
||||||
|
if(Arrays.class.equals(items.getClass().getEnclosingClass()))
|
||||||
|
items = new ArrayList<>(items);
|
||||||
|
return asizeP(items,length,failSumsArray,failSum,r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <X> List<X> asize(X[] items,int length,Integer[] failSumsArray,int failSum,Random r){
|
||||||
|
return asize(Arrays.asList(items),length,failSumsArray,failSum,r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <X> List<X> asizeP(List<X> items,int length,Integer[] failSumsArray,int failSum,Random r){
|
||||||
|
Log.d("asizement","asizeP("+items.toString()+","+length+","+Arrays.toString(failSumsArray)+","+failSum+",random)");
|
||||||
|
ArrayList<Integer> failSums = new ArrayList<>(Arrays.asList(failSumsArray));
|
||||||
|
ArrayList<X> finalItems = new ArrayList<>();
|
||||||
|
if(items.size() <= 0)Log.e("ArrayInutil","List empty !"+items.add(null));
|
||||||
|
if(items.size() < length){
|
||||||
|
int n = (int) Math.floor(length / items.size());
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
finalItems.addAll(items);
|
||||||
|
}
|
||||||
|
int currentFailSum = failSum;
|
||||||
|
while(finalItems.size()<length){
|
||||||
|
Log.d("Condition",finalItems.size()+"<"+length);
|
||||||
|
int ran = r.nextInt(currentFailSum + 1);
|
||||||
|
int total = 0;
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
total+=failSums.get(i);
|
||||||
|
if(total >= ran){
|
||||||
|
currentFailSum -= failSums.get(i);
|
||||||
|
finalItems.add(items.get(i));
|
||||||
|
failSums.remove(i);
|
||||||
|
items.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.shuffle(finalItems,r);
|
||||||
|
return finalItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <X> Map<X,Integer> count(List<X> items){
|
||||||
|
Map<X,Integer> out = new HashMap<>();
|
||||||
|
for (X x:items) {
|
||||||
|
X key = null;
|
||||||
|
for (X k:out.keySet())
|
||||||
|
if(x.equals(k))
|
||||||
|
key = k;
|
||||||
|
if (key == null)
|
||||||
|
out.put(x, 1);
|
||||||
|
else
|
||||||
|
out.put(key, out.get(x) + 1);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long[] toObjectArray(long[] array){
|
||||||
|
Long[] out = new Long[array.length];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = array[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[] toObjectArray(int[] array){
|
||||||
|
Integer[] out = new Integer[array.length];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = array[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long[][] toObjectArray(long[][] array){
|
||||||
|
Long[][] out = new Long[array.length][];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = toObjectArray(array[i]);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[][] toObjectArray(int[][] array){
|
||||||
|
Integer[][] out = new Integer[array.length][];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = toObjectArray(array[i]);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long[] toPrimitiveArray(Long[] array){
|
||||||
|
long[] out = new long[array.length];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = array[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] toPrimitiveArray(Integer[] array){
|
||||||
|
int[] out = new int[array.length];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = array[i];
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long[][] toPrimitiveArray(Long[][] array){
|
||||||
|
long[][] out = new long[array.length][];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = toPrimitiveArray(array[i]);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[][] toPrimitiveArray(Integer[][] array){
|
||||||
|
int[][] out = new int[array.length][];
|
||||||
|
for (int i = 0; i < out.length; i++)
|
||||||
|
out[i] = toPrimitiveArray(array[i]);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> boolean inArray (T needle, T[] haystack){
|
||||||
|
for(T item : haystack)
|
||||||
|
if(item.equals(needle))return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer[] range (int low, int high){
|
||||||
|
Integer[] result = new Integer[high-low];
|
||||||
|
for(int i = 0;i<high-low;i++)
|
||||||
|
result[i] = low + i;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> int indexOf(T[] haystack, T needle) {
|
||||||
|
for (int i = 0; i < haystack.length; i++) {
|
||||||
|
if(haystack[i] != null && haystack[i].equals(needle))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void removeIndex(T[] array, int index) {
|
||||||
|
System.arraycopy(array,index+1,array,index, array.length-index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package com.bernard.mcqinator.inutil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 23/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ClassInutil {
|
||||||
|
|
||||||
|
public static Class[] getAllInterface(Class c){
|
||||||
|
List<Class> clazz = getAllInterface(c,new ArrayList<Class>());
|
||||||
|
Class[] clazarray = new Class[clazz.size()];
|
||||||
|
clazz.toArray(clazarray);
|
||||||
|
return clazarray;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Class> getAllInterface(Class c,List<Class> l){
|
||||||
|
for(Class k : c.getInterfaces()){
|
||||||
|
l.add(k);
|
||||||
|
getAllInterface(k,l);
|
||||||
|
}
|
||||||
|
if(c.getSuperclass() != null)
|
||||||
|
getAllInterface(c.getSuperclass(),l);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.bernard.mcqinator.inutil;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 23/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class NumberInutil {
|
||||||
|
|
||||||
|
private static final DecimalFormat zero19 = new DecimalFormat("0000000000000000000");
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author JohnS from stackoverflow
|
||||||
|
*/
|
||||||
|
public static String toUnsignedString(long x) {
|
||||||
|
if (x >= 0)
|
||||||
|
return "0" + zero19.format(x);
|
||||||
|
else if (x >= -8446744073709551616L)
|
||||||
|
return "1" + zero19.format(x + 8446744073709551616L);
|
||||||
|
else
|
||||||
|
return "09" + (x - 9000000000000000000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int exclude(int n,int toExclude){
|
||||||
|
return (n < toExclude)?n:n+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
71
app/src/main/java/com/bernard/mcqinator/inutil/Pair.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package com.bernard.mcqinator.inutil;
|
||||||
|
|
||||||
|
public class Pair<A,B> {
|
||||||
|
|
||||||
|
public static <P, Q> Pair<P, Q> makePair(P p, Q q) {
|
||||||
|
return new Pair<>(p, q);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final A a;
|
||||||
|
public final B b;
|
||||||
|
|
||||||
|
public Pair(A a, B b) {
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((a == null) ? 0 : a.hashCode());
|
||||||
|
result = prime * result + ((b == null) ? 0 : b.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
Pair other = (Pair) obj;
|
||||||
|
if (a == null) {
|
||||||
|
if (other.a != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!a.equals(other.a)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (b == null) {
|
||||||
|
if (other.b != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!b.equals(other.b)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInstance(Class<?> classA, Class<?> classB) {
|
||||||
|
return classA.isInstance(a) && classB.isInstance(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <P, Q> Pair<P, Q> cast(Pair<?, ?> pair, Class<P> pClass, Class<Q> qClass) {
|
||||||
|
|
||||||
|
if (pair.isInstance(pClass, qClass)) {
|
||||||
|
return (Pair<P, Q>) pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ClassCastException();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,110 @@
|
|||||||
|
package com.bernard.mcqinator.inutil.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 04/08/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class WaitingDialog extends Dialog {
|
||||||
|
|
||||||
|
public WaitingDialog(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
LinearLayout ll;
|
||||||
|
Stack<ViewGroup> barsLayout;
|
||||||
|
ViewGroup parent;
|
||||||
|
LayoutInflater inflater;
|
||||||
|
Activity a;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.waitdialog_layout);
|
||||||
|
this.inflater = getLayoutInflater();
|
||||||
|
ll = findViewById(R.id.waitList);
|
||||||
|
|
||||||
|
barsLayout = new Stack<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Activity ownerActivity(){
|
||||||
|
Activity oA = getOwnerActivity();
|
||||||
|
if(oA == null)
|
||||||
|
throw new IllegalStateException("The owner's activity is null ... and it should not");
|
||||||
|
return oA;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int newBar(){
|
||||||
|
ownerActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ViewGroup barLayout = (ViewGroup)inflater.inflate(R.layout.waitdialog_progressbar,ll,true);
|
||||||
|
barsLayout.push(barLayout);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return barsLayout.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int newBar(int max){
|
||||||
|
newBar();
|
||||||
|
setMax(max);
|
||||||
|
return barsLayout.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProgressBar getProgressBar(){
|
||||||
|
return ((ProgressBar)barsLayout.peek().findViewById(R.id.progressBar));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextView getProgressText(){
|
||||||
|
return ((TextView)barsLayout.peek().findViewById(R.id.progressText));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(final int max){
|
||||||
|
ownerActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ProgressBar bar = getProgressBar();
|
||||||
|
bar.setMax(max);
|
||||||
|
getProgressText().setText(bar.getProgress() + "/" + bar.getMax());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(final int value){
|
||||||
|
ownerActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ProgressBar bar = getProgressBar();
|
||||||
|
bar.setProgress(value);
|
||||||
|
getProgressText().setText(bar.getProgress() + "/" + bar.getMax());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int removeBar(){
|
||||||
|
ownerActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ll.removeView(barsLayout.pop());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return barsLayout.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
package com.bernard.mcqinator.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 17/04/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class QuizAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
private final List<QuizMetadata> items;
|
||||||
|
private final Context ctx;
|
||||||
|
|
||||||
|
public QuizAdapter(List<QuizMetadata> quizz,Context context){
|
||||||
|
this.items = quizz;
|
||||||
|
this.ctx = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QuizMetadata getItem(int position) {
|
||||||
|
return items.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 42;//Use is up to the developer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
final View mainView;
|
||||||
|
if(convertView != null)
|
||||||
|
mainView = convertView;
|
||||||
|
else
|
||||||
|
mainView = LayoutInflater.from(ctx).inflate(R.layout.quiz_row_layout,parent,false);
|
||||||
|
|
||||||
|
TextView nameText;
|
||||||
|
TextView authorText;
|
||||||
|
ImageView iconView;
|
||||||
|
|
||||||
|
try {
|
||||||
|
nameText = mainView.findViewById(R.id.quizAdapterName);
|
||||||
|
authorText = mainView.findViewById(R.id.quizAdapterAuthor);
|
||||||
|
iconView = mainView.findViewById(R.id.quizAdapterIcon);
|
||||||
|
|
||||||
|
if (nameText == null)
|
||||||
|
throw new RuntimeException("Failed to find view with ID quizAdapterName in layout");
|
||||||
|
if (authorText == null)
|
||||||
|
throw new RuntimeException("Failed to find view with ID quizAdapterAuthor in layout");
|
||||||
|
if (iconView == null)
|
||||||
|
throw new RuntimeException("Failed to find view with ID quizAdapterIcon in layout");
|
||||||
|
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
Log.e("QuizAdapter", "Id quizAdapterName and quizAdapterAuthor must be a TextView and quizAdapterIcon must be an ImageView");
|
||||||
|
throw new IllegalStateException("QuizAdapter'layout ids didn't match the right types", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
final QuizMetadata quiz = getItem(position);
|
||||||
|
if(quiz != null) {
|
||||||
|
nameText.setText(quiz.getName());
|
||||||
|
authorText.setText(quiz.getAuthor());
|
||||||
|
iconView.setImageDrawable(ContextCompat.getDrawable(ctx,quiz.getType().getQuizIconID()));
|
||||||
|
}
|
||||||
|
return mainView;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,168 @@
|
|||||||
|
package com.bernard.mcqinator.view;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.TranslateAnimation;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date 17/04/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class TextBackgroundManager {
|
||||||
|
|
||||||
|
private static final Random textRandom = new Random();
|
||||||
|
private static String[] deWorte;
|
||||||
|
private Integer[] worteYArray;
|
||||||
|
private final Activity activity;
|
||||||
|
private TextView[] floatingTexts;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public TextBackgroundManager(Activity activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
//TODO rearrange preferences
|
||||||
|
switch(PreferenceManager.getDefaultSharedPreferences(activity).getInt("preferedTheme",0)){
|
||||||
|
case 0:
|
||||||
|
activity.setTheme(R.style.DarkTheme);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
activity.setTheme(R.style.LightTheme);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(deWorte == null)
|
||||||
|
deWorte = activity.getResources().getStringArray(R.array.randomWorte);
|
||||||
|
final View rout = activity.findViewById(android.R.id.content);
|
||||||
|
rout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
// gets called after layout has been done but before display
|
||||||
|
/*
|
||||||
|
TypedArray styledAttributes = TextBackgroundManager.this.activity.obtainStyledAttributes(new int[]{android.R.attr.textSize});
|
||||||
|
Pattern p = Pattern.compile("^[0-9]+");
|
||||||
|
String textSize = styledAttributes.hasValue(0)?styledAttributes.getString(0):"12";
|
||||||
|
Matcher m = p.matcher(textSize);
|
||||||
|
Log.d("TXTS",textSize);
|
||||||
|
*/
|
||||||
|
final int txtHeight = 20;
|
||||||
|
final int totalHeight = rout.getHeight();
|
||||||
|
int currentPos = textRandom.nextInt(txtHeight);
|
||||||
|
List<Integer> tempYArray = new ArrayList<>();
|
||||||
|
while (currentPos < totalHeight) {
|
||||||
|
tempYArray.add(currentPos);
|
||||||
|
currentPos += txtHeight;
|
||||||
|
currentPos += textRandom.nextInt(8) - 4;
|
||||||
|
}
|
||||||
|
worteYArray = new Integer[tempYArray.size()];
|
||||||
|
tempYArray.toArray(worteYArray);
|
||||||
|
rout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
floatingTexts = new TextView[worteYArray.length];
|
||||||
|
for (int i = 0; i < worteYArray.length; i++)
|
||||||
|
floatingTexts[i] = launchText(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextView launchText(int x){
|
||||||
|
final TextView tv = new TextView(activity);
|
||||||
|
tv.setText(deWorte[textRandom.nextInt(deWorte.length)]);
|
||||||
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
params.leftMargin = -tv.getWidth();
|
||||||
|
params.topMargin = worteYArray[x];
|
||||||
|
tv.setLayoutParams(params);
|
||||||
|
((ViewGroup)activity.findViewById(android.R.id.content)).addView(tv,0);
|
||||||
|
tv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
|
||||||
|
TranslateAnimation anim = new TranslateAnimation(-tv.getWidth(), tv.getWidth(), 0, 0);
|
||||||
|
anim.setDuration(8000 + textRandom.nextInt(1000));
|
||||||
|
anim.setStartOffset(textRandom.nextInt(9000));
|
||||||
|
anim.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animation animation) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animation animation) {
|
||||||
|
tv.setText(deWorte[textRandom.nextInt(deWorte.length)]);
|
||||||
|
TranslateAnimation anim = new TranslateAnimation(-tv.getWidth(), tv.getWidth(), 0, 0);
|
||||||
|
anim.setDuration(8000 + textRandom.nextInt(1000));
|
||||||
|
anim.setAnimationListener(this);
|
||||||
|
tv.startAnimation(anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animation animation) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tv.startAnimation(anim);
|
||||||
|
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopTexts(){
|
||||||
|
if(floatingTexts == null)return;
|
||||||
|
for (TextView t:floatingTexts) {
|
||||||
|
t.clearAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restartTexts(){
|
||||||
|
if(floatingTexts == null)return;
|
||||||
|
for (final TextView tv:floatingTexts) {
|
||||||
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
params.leftMargin = -tv.getWidth();
|
||||||
|
params.topMargin = ((FrameLayout.LayoutParams)tv.getLayoutParams()).topMargin;
|
||||||
|
tv.setLayoutParams(params);
|
||||||
|
tv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
|
||||||
|
TranslateAnimation anim = new TranslateAnimation(-tv.getWidth(), tv.getWidth(), 0, 0);
|
||||||
|
anim.setDuration(8000 + textRandom.nextInt(1000));
|
||||||
|
anim.setStartOffset(textRandom.nextInt(9000));
|
||||||
|
anim.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animation animation) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animation animation) {
|
||||||
|
tv.setText(deWorte[textRandom.nextInt(deWorte.length)]);
|
||||||
|
TranslateAnimation anim = new TranslateAnimation(-tv.getWidth(), tv.getWidth(), 0, 0);
|
||||||
|
anim.setDuration(8000 + textRandom.nextInt(1000));
|
||||||
|
anim.setAnimationListener(this);
|
||||||
|
tv.startAnimation(anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animation animation) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tv.startAnimation(anim);
|
||||||
|
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Random getRandom() {
|
||||||
|
return textRandom;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.QuizAdapter;
|
||||||
|
import com.bernard.mcqinator.view.TextBackgroundManager;
|
||||||
|
|
||||||
|
public class ChoosingQuizActivity extends ListActivity {
|
||||||
|
|
||||||
|
TextBackgroundManager tbm;
|
||||||
|
QuizAdapter qa;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_choosing_quiz);
|
||||||
|
tbm = new TextBackgroundManager(this);
|
||||||
|
|
||||||
|
qa = new QuizAdapter(QuizMetadataManager.getAll(this),this);
|
||||||
|
setListAdapter(qa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
tbm.stopTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
tbm.restartTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
Intent i = new Intent(this,ConfiguringQuizActivity.class);
|
||||||
|
i.putExtra(ConfiguringQuizActivity.QUIZID,qa.getItem(position).getFileID());
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.TextBackgroundManager;
|
||||||
|
import com.bernard.mcqinator.view.QuizAdapter;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
|
||||||
|
public class ChoosingQuizToEditActivity extends ListActivity {
|
||||||
|
|
||||||
|
public static final String QUIZ_FILEID = "com.bernard.qcminator.quizFileID";
|
||||||
|
|
||||||
|
TextBackgroundManager tbm;
|
||||||
|
QuizAdapter qa;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_choosing_quiz_to_edit);
|
||||||
|
tbm = new TextBackgroundManager(this);
|
||||||
|
|
||||||
|
Button createQuizButton = findViewById(R.id.newQuizButton);
|
||||||
|
createQuizButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(ChoosingQuizToEditActivity.this,CreateQuizActivity.class);
|
||||||
|
//No data to transfer
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
qa = new QuizAdapter(QuizMetadataManager.getAllQuiz(this,true), this);
|
||||||
|
setListAdapter(qa);
|
||||||
|
tbm.stopTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
tbm.restartTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
QuizMetadata selected = qa.getItem(position);
|
||||||
|
|
||||||
|
if(selected == null) {
|
||||||
|
Log.e("EditQuiz","Trying to edit a null quiz ... aborting");
|
||||||
|
Toast.makeText(this, "Cannot edit quiz", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent i = new Intent(ChoosingQuizToEditActivity.this,selected.getType().getEditActivityClass());
|
||||||
|
|
||||||
|
i.putExtra(ChoosingQuizToEditActivity.QUIZ_FILEID,selected.getFileID());
|
||||||
|
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,237 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.IdentifiedQuiz;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.api.frageable.Frageable;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
import com.bernard.mcqinator.api.fragenStats.QuizStat;
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
import com.bernard.mcqinator.controller.FileManager;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.inutil.ClassInutil;
|
||||||
|
import com.bernard.mcqinator.view.activities.congratsActivity.CongratsActivity;
|
||||||
|
import com.bernard.mcqinator.view.activities.fragenActivities.FrageActivity;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ConfiguringQuizActivity extends Activity implements AdapterView.OnItemClickListener,View.OnClickListener{
|
||||||
|
|
||||||
|
public static final String QUIZID = "com.bernard.qcminator.QUIZID";
|
||||||
|
private static final int MAKE_QUIZ = 0x6C98E2AA;
|
||||||
|
private static final int CONGRATS_QUIZ = 0x2843124F;
|
||||||
|
public ProgressDialog fragment;
|
||||||
|
|
||||||
|
QuizMetadata q;
|
||||||
|
Quiz quiz;
|
||||||
|
|
||||||
|
FrameLayout frame;
|
||||||
|
ListView list;
|
||||||
|
View actualView;
|
||||||
|
Button go;
|
||||||
|
Frage[] fragen;
|
||||||
|
LinkedHashMap<Class,View> classes;// <The XFrageable class,The hided view with settings>
|
||||||
|
LinkedHashMap<Class,Frageable.Configurator> configurators;// <The XFrageable class,Configurator>
|
||||||
|
private Class actualClass;
|
||||||
|
private Frage.Identifier storedIdentifier;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_configuring_quiz);
|
||||||
|
long quizID = getIntent().getLongExtra(QUIZID,-1L);
|
||||||
|
if(quizID == -1L)throw new IllegalArgumentException("Missing long "+QUIZID+" in the intent");
|
||||||
|
q = QuizMetadataManager.getQuiz(this,quizID);
|
||||||
|
|
||||||
|
frame = findViewById(R.id.attributesFrame);
|
||||||
|
list = findViewById(android.R.id.list);
|
||||||
|
go = findViewById(R.id.doneButton);
|
||||||
|
|
||||||
|
fragment = new ProgressDialog(ConfiguringQuizActivity.this);
|
||||||
|
|
||||||
|
classes = new LinkedHashMap<>();
|
||||||
|
configurators = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for (Class i : ClassInutil.getAllInterface(q.getType().getQuizClass())) {
|
||||||
|
if(!Frageable.class.isAssignableFrom(i))
|
||||||
|
continue;
|
||||||
|
try {
|
||||||
|
Class configuratorClass = Class.class.cast(i.getField("CONFIGURATOR").get(null));
|
||||||
|
Frageable.Configurator configurator = (Frageable.Configurator) configuratorClass.newInstance();
|
||||||
|
View added = configurator.attachConfigLayout(this,frame);
|
||||||
|
added.setVisibility(View.GONE);
|
||||||
|
configurators.put(i,configurator);
|
||||||
|
classes.put(i,added);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.e("ClassError","The field CONFIGURATOR of the class "+i+" is not public");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
Log.e("ClassError","The class "+i+" don't have the field CONFIGURATOR");
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
Log.e("ClassError","Cannot instantiate the CONFIGURATOR of class "+i+" , do you have a public constructor ?");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
Log.e("ClassError","The CONFIGURATOR of class "+i+" is not a Class<? extends Frageable.Configurator>");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Log.d("ConfiguringQuizActivity","Quiz Frageable Classes : " + classes.toString());
|
||||||
|
list.setAdapter(new QuizFrageableAdapter());
|
||||||
|
list.setOnItemClickListener(this);
|
||||||
|
|
||||||
|
go.setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void launchQuiz(final Frageable.Data data){
|
||||||
|
final Context me = this;
|
||||||
|
Thread t = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
quiz = FileManager.getQuiz(q,me);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("ConfiguringQuizActivity","Cannot retieve Quiz data ... aborting quiz launch",e);
|
||||||
|
}
|
||||||
|
if(quiz == null)
|
||||||
|
Toast.makeText(me, R.string.cannotLaunchQuiz, Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fragment.setTitle("WaitingDialog");
|
||||||
|
fragment.setMessage("Chargement de votre quiz en cours ...");
|
||||||
|
fragment.setIndeterminate(true);
|
||||||
|
fragment.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Frageable f = (Frageable)quiz;
|
||||||
|
|
||||||
|
QuizStat stats = FileManager.getStat(q,me);
|
||||||
|
if(stats == null){
|
||||||
|
stats = QuizStat.createStat(q.getType().getQuizStatClass(),quiz);
|
||||||
|
FileManager.saveStat(q,stats,me);
|
||||||
|
}
|
||||||
|
IdentifiedQuiz identifiedQuiz = checkedGenFragen(f,stats,data,fragment);
|
||||||
|
storedIdentifier = identifiedQuiz.getIdentifier();
|
||||||
|
fragen = identifiedQuiz.getFragen();
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fragment.hide();
|
||||||
|
Intent i = new Intent(ConfiguringQuizActivity.this,data.getFrageActivityClass());
|
||||||
|
i.putExtra(FrageActivity.FRAGEN,fragen);
|
||||||
|
i.putExtra(FrageActivity.QUIZ_DATA,data);
|
||||||
|
startActivityForResult(i,ConfiguringQuizActivity.MAKE_QUIZ);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},"QuizLauncherThread");
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private IdentifiedQuiz checkedGenFragen(Frageable f, QuizStat stats, Frageable.Data data, ProgressDialog wait){
|
||||||
|
return f.genFragen(stats,data,this,wait);//Normal Warning
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if(requestCode == MAKE_QUIZ && resultCode == RESULT_OK){
|
||||||
|
ArrayList<? extends Frage.Reply> repliesList = data.getParcelableArrayListExtra(FrageActivity.REPLIES);
|
||||||
|
QuizStat stats = FileManager.getStat(q,this);
|
||||||
|
stats = checkedUpdateStats((Frageable) quiz,stats,repliesList,storedIdentifier);
|
||||||
|
FileManager.saveStat(q,stats,this);
|
||||||
|
Intent i = new Intent(ConfiguringQuizActivity.this,q.getType().getCongratsActivityClass());
|
||||||
|
i.putExtra(CongratsActivity.FRAGEN,fragen);
|
||||||
|
i.putParcelableArrayListExtra(CongratsActivity.REPLIES,repliesList);
|
||||||
|
i.putExtra(CongratsActivity.QUIZ_DATA,q);
|
||||||
|
startActivityForResult(i,ConfiguringQuizActivity.CONGRATS_QUIZ);
|
||||||
|
}else if(requestCode == CONGRATS_QUIZ && resultCode == RESULT_OK){
|
||||||
|
Log.d("ConfiguringQuizActivity","Congrats made !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private QuizStat checkedUpdateStats(Frageable f, QuizStat stats, List<? extends Frage.Reply> replies, Frage.Identifier identifier){
|
||||||
|
return f.updateStats(stats,replies,identifier);//Normal Warning
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
if(actualView != null)
|
||||||
|
actualView.setVisibility(View.GONE);
|
||||||
|
Map.Entry[] entries = new Map.Entry[classes.size()];
|
||||||
|
classes.entrySet().toArray(entries);
|
||||||
|
actualClass = (Class) entries[position].getKey();
|
||||||
|
actualView = classes.get(actualClass);
|
||||||
|
actualView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(actualClass == null)return;
|
||||||
|
Frageable.Configurator configurator = configurators.get(actualClass);
|
||||||
|
Frageable.Data data = configurator.genDataFromConfigLayout(actualView);
|
||||||
|
launchQuiz(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class QuizFrageableAdapter extends BaseAdapter{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return classes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class getItem(int position) {
|
||||||
|
return (Class) classes.keySet().toArray()[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ViewGroup lay;
|
||||||
|
TextView text;
|
||||||
|
ImageView image;
|
||||||
|
if(convertView == null)
|
||||||
|
lay = (ViewGroup)getLayoutInflater().inflate(R.layout.quiz_typ_row_layout,parent,false);
|
||||||
|
else
|
||||||
|
lay = (ViewGroup)convertView;
|
||||||
|
text = lay.findViewById(R.id.quizTypText);
|
||||||
|
image = lay.findViewById(R.id.quizTypIcon);
|
||||||
|
Frageable.Configurator configurator = configurators.get(getItem(position));
|
||||||
|
text.setText(configurator.getTypStringID());
|
||||||
|
int drawableID = configurator.getIconDrawableID();
|
||||||
|
image.setImageDrawable(getDrawable(drawableID));
|
||||||
|
|
||||||
|
|
||||||
|
return lay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.TextBackgroundManager;
|
||||||
|
import com.bernard.mcqinator.view.QuizAdapter;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO make text "no installed quiz" diseapear
|
||||||
|
*/
|
||||||
|
public class CreateQuizActivity extends Activity implements AdapterView.OnItemSelectedListener{
|
||||||
|
|
||||||
|
ArrayAdapter<QuizMetadata.Type> sadapter;
|
||||||
|
TextBackgroundManager tbm;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_create_quiz);
|
||||||
|
tbm = new TextBackgroundManager(this);
|
||||||
|
|
||||||
|
final EditText nameText = findViewById(R.id.quizNameAsk);
|
||||||
|
final EditText authorText = findViewById(R.id.quizAuthorAsk);
|
||||||
|
|
||||||
|
//Type select spiner
|
||||||
|
final int defaultSelectIndex = 0;
|
||||||
|
final Spinner sp = findViewById(R.id.quizTypeAsk);
|
||||||
|
sadapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,QuizMetadata.Type.values());
|
||||||
|
sadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
sp.setAdapter(sadapter);
|
||||||
|
sp.setOnItemSelectedListener(this);
|
||||||
|
sp.setSelection(defaultSelectIndex);
|
||||||
|
|
||||||
|
//Parent quiz list
|
||||||
|
final ListView lv = findViewById(R.id.quizParentChoose);
|
||||||
|
QuizAdapter adapter = new QuizAdapter(QuizMetadataManager.getAllQuiz(this,sadapter.getItem(defaultSelectIndex)),this);
|
||||||
|
lv.setAdapter(adapter);
|
||||||
|
|
||||||
|
//Has parent checkbox
|
||||||
|
final CheckBox hasParentBox = findViewById(R.id.quizHasParentAsk);
|
||||||
|
hasParentBox.setSelected(false);
|
||||||
|
hasParentBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
|
lv.setEnabled(isChecked);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button go = findViewById(R.id.doneButton);
|
||||||
|
go.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
QuizMetadata.Type quizType = (QuizMetadata.Type) sp.getSelectedItem();
|
||||||
|
String name = nameText.getText().toString();
|
||||||
|
if(name.isEmpty()){
|
||||||
|
Toast.makeText(CreateQuizActivity.this,R.string.quizNameEmpty,Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String author = authorText.getText().toString();
|
||||||
|
if(author.isEmpty()){
|
||||||
|
Toast.makeText(CreateQuizActivity.this,R.string.quizAuthorEmpty,Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent i = new Intent(CreateQuizActivity.this,quizType.getEditActivityClass());
|
||||||
|
|
||||||
|
QuizMetadata creation;
|
||||||
|
|
||||||
|
if (hasParentBox.isChecked()) {
|
||||||
|
if(lv.getSelectedItem() == null){
|
||||||
|
Toast.makeText(CreateQuizActivity.this,R.string.quizParentEmpty,Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QuizMetadata parent = (QuizMetadata) lv.getSelectedItem();
|
||||||
|
creation = QuizMetadataManager.createQuiz(CreateQuizActivity.this,name,author,true,parent);
|
||||||
|
|
||||||
|
} else
|
||||||
|
creation = QuizMetadataManager.createQuiz(CreateQuizActivity.this, name, author, quizType, true);
|
||||||
|
|
||||||
|
i.putExtra(ChoosingQuizToEditActivity.QUIZ_FILEID,creation.getFileID());
|
||||||
|
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
ListView lv = findViewById(R.id.quizParentChoose);
|
||||||
|
QuizAdapter adapter = new QuizAdapter(QuizMetadataManager.getAllQuiz(this,sadapter.getItem(position)),this);
|
||||||
|
lv.setAdapter(adapter);
|
||||||
|
TextView nothingText = findViewById(R.id.quizParentAskNoQuiz);
|
||||||
|
if(adapter.getCount()<1){
|
||||||
|
lv.setVisibility(View.GONE);
|
||||||
|
nothingText.setVisibility(View.VISIBLE);
|
||||||
|
}else{
|
||||||
|
lv.setVisibility(View.VISIBLE);
|
||||||
|
nothingText.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.TextBackgroundManager;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
|
//TODO add a global javadoc
|
||||||
|
//TODO add a global argument check with exceptions
|
||||||
|
|
||||||
|
TextBackgroundManager tbm;
|
||||||
|
public static final String PREFERENCES_FILE_KEY = "com.bernard.qcminator.SAXOPHONE";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
tbm = new TextBackgroundManager(this);
|
||||||
|
|
||||||
|
final Button takeQuiz = findViewById(R.id.takeQuizButton);
|
||||||
|
takeQuiz.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(MainActivity.this,ChoosingQuizActivity.class);
|
||||||
|
//No data to transfer
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final Button manageQuiz = findViewById(R.id.manageMyQuizButton);
|
||||||
|
manageQuiz.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(MainActivity.this,QuizManagerActivity.class);
|
||||||
|
//No data to transfer
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final Button createQuiz = findViewById(R.id.createQuizButton);
|
||||||
|
createQuiz.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(MainActivity.this,ChoosingQuizToEditActivity.class);
|
||||||
|
//No data to transfer
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final Button options = findViewById(R.id.optionsButton);
|
||||||
|
createQuiz.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//Intent i = new Intent(MainActivity.this,ChoosingQuizToEditActivity.class);
|
||||||
|
//No data to transfer
|
||||||
|
//startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
options.setEnabled(false);
|
||||||
|
|
||||||
|
Thread t = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
QuizMetadataManager.retieveSavedQuizList(MainActivity.this);
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
findViewById(R.id.loading).setVisibility(View.GONE);
|
||||||
|
takeQuiz.setEnabled(true);
|
||||||
|
manageQuiz.setEnabled(true);
|
||||||
|
createQuiz.setEnabled(true);
|
||||||
|
//options.setEnabled(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
t.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
tbm.stopTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
tbm.restartTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
QuizMetadataManager.saveSavedQuizList(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,271 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.controller.FileManager;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.QuizAdapter;
|
||||||
|
import com.bernard.mcqinator.view.TextBackgroundManager;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class QuizManagerActivity extends ListActivity{
|
||||||
|
|
||||||
|
TextBackgroundManager tbm;
|
||||||
|
public static final String VICTIM_QUIZ_FILEID = "com.bernard.qcminator.VICTIM_QUIZ_FILEID";
|
||||||
|
public static final int CHOOSING_FILE_TO_IMPORT = 0x55BB2B3A;
|
||||||
|
QuizAdapter qa;
|
||||||
|
|
||||||
|
//////////// Activity lifecycle ////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_quiz_manager);
|
||||||
|
tbm = new TextBackgroundManager(this);
|
||||||
|
|
||||||
|
Button importQuiz = findViewById(R.id.importQuiz);
|
||||||
|
importQuiz.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
i.setType("file/*");
|
||||||
|
try{
|
||||||
|
startActivityForResult(Intent.createChooser(i,"Select a file to import"),CHOOSING_FILE_TO_IMPORT);
|
||||||
|
}catch(ActivityNotFoundException e){
|
||||||
|
Toast.makeText(QuizManagerActivity.this, R.string.noFileReader, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
reloadQuizz();
|
||||||
|
tbm.stopTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart() {
|
||||||
|
super.onRestart();
|
||||||
|
tbm.restartTexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadQuizz(){
|
||||||
|
qa = new QuizAdapter(QuizMetadataManager.getAll(this),this);
|
||||||
|
setListAdapter(qa);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////// Listeners ////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
DialogFragment fragment = new WhatToDoToQuiz();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong(VICTIM_QUIZ_FILEID,qa.getItem(position).getFileID());
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.show(getFragmentManager(),"QuizWhatToDo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if(requestCode == CHOOSING_FILE_TO_IMPORT && resultCode == RESULT_OK){
|
||||||
|
String path = data.getData().getPath();
|
||||||
|
Log.d("Import file","Importing "+path);
|
||||||
|
try {
|
||||||
|
File f = new File(path);
|
||||||
|
if(!f.canRead()){
|
||||||
|
Toast.makeText(this, R.string.unreadableFile, Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuizMetadata meta = FileManager.importQuizFromFile(this,f);
|
||||||
|
QuizMetadataManager.saveSavedQuizList(this);
|
||||||
|
assert meta != null;
|
||||||
|
Toast.makeText(this, getResources().getString(R.string.successfullyImportedQuiz, meta.getName()), Toast.LENGTH_LONG).show();
|
||||||
|
} catch (IOException | NullPointerException | AssertionError e) {
|
||||||
|
Log.e("ImportQuiz","Failed importing quiz",e);
|
||||||
|
Toast.makeText(this, getResources().getString(R.string.failedImportQuiz), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////// Internal classes ////////////
|
||||||
|
|
||||||
|
////// Dialogs //////
|
||||||
|
|
||||||
|
public static class WhatToDoToQuiz extends DialogFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
builder.setTitle(R.string.whatToDoToQuiz)
|
||||||
|
.setItems(R.array.quizManageOption, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (which) {
|
||||||
|
case 0://Delete
|
||||||
|
DialogFragment fragment = new ReallyWantToDelete();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong(VICTIM_QUIZ_FILEID, getArguments().getLong(VICTIM_QUIZ_FILEID));
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.show(getFragmentManager(), "QuizReallyWantToDelete");
|
||||||
|
break;
|
||||||
|
case 1://Export
|
||||||
|
QuizMetadata q = QuizMetadataManager.getQuiz(getActivity(),getArguments().getLong(VICTIM_QUIZ_FILEID));
|
||||||
|
if(q == null){
|
||||||
|
Log.e("ExportQuiz","Quiz not found");
|
||||||
|
Toast.makeText(getActivity(), "Cannot export quiz ... quiz not found", Toast.LENGTH_SHORT).show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String fileName;
|
||||||
|
File f;
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
fileName = q.getName() + "-" + q.getAuthor() + ((i!=0)?("("+i+")"):"") +".bernard";
|
||||||
|
i++;
|
||||||
|
}while((f = new File(getActivity().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),fileName)).exists());
|
||||||
|
try {
|
||||||
|
if(!f.createNewFile())throw new IOException("The file exists ... this error is nor supposed to be");
|
||||||
|
FileManager.exportQuizToFile(q,getActivity(),f);
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.successfullyExportQuizTo,fileName), Toast.LENGTH_SHORT).show();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.d("ExportFile","Can't export the file to "+fileName,e);
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.failedExportQuizTo,fileName), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2://Duplicate
|
||||||
|
DialogFragment fragment3 = new DuplicateOptions();
|
||||||
|
Bundle args3 = new Bundle();
|
||||||
|
args3.putLong(VICTIM_QUIZ_FILEID, getArguments().getLong(VICTIM_QUIZ_FILEID));
|
||||||
|
fragment3.setArguments(args3);
|
||||||
|
fragment3.show(getFragmentManager(), "QuizReallyWantToDelete");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReallyWantToDelete extends DialogFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
super.onDismiss(dialog);
|
||||||
|
if(getActivity() instanceof QuizManagerActivity)
|
||||||
|
((QuizManagerActivity)getActivity()).reloadQuizz();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
builder.setMessage(R.string.reallyWantToDelete)
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
QuizMetadata q = QuizMetadataManager.getQuiz(getActivity(),getArguments().getLong(VICTIM_QUIZ_FILEID));
|
||||||
|
if (q == null) {
|
||||||
|
Log.e("DeleteQuiz", "The quiz reference was null, cannot delete quiz");
|
||||||
|
Toast.makeText(getActivity(), R.string.cannotDeleteQuiz, Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (FileManager.delete(q,getActivity()))
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.successfullyDeleteQuiz, q.getName()), Toast.LENGTH_LONG).show();
|
||||||
|
else
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.failedDeleteQuiz, q.getName()), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Toast.makeText(getActivity(), android.R.string.ok, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DuplicateOptions extends DialogFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
super.onDismiss(dialog);
|
||||||
|
if(getActivity() instanceof QuizManagerActivity)
|
||||||
|
((QuizManagerActivity)getActivity()).reloadQuizz();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("InflateParams")
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
|
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||||
|
builder.setMessage(R.string.newDuplicateData)
|
||||||
|
.setView(inflater.inflate(R.layout.duplication_options_layout, null,false))
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Context c = getActivity();
|
||||||
|
QuizMetadata q = QuizMetadataManager.getQuiz(getActivity(),getArguments().getLong(VICTIM_QUIZ_FILEID));
|
||||||
|
if (q == null) {
|
||||||
|
Log.d("DuplicateQuiz", "The quiz reference was null, cannot duplicate quiz");
|
||||||
|
Toast.makeText(getActivity(), R.string.failedDuplicateQuiz, Toast.LENGTH_LONG).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String newName = ((EditText)getDialog().findViewById(R.id.newNameAsk)).getText().toString();
|
||||||
|
String newAuthor = ((EditText)getDialog().findViewById(R.id.newAuthorAsk)).getText().toString();
|
||||||
|
if(newAuthor.isEmpty())
|
||||||
|
newAuthor = q.getAuthor();
|
||||||
|
try {
|
||||||
|
QuizMetadataManager.createQuiz(c,newName,newAuthor,true,q);
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.successfullyDuplicateQuiz, q.getName()), Toast.LENGTH_LONG).show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("Quizduplication","Cannot duplicate quiz : ",e);
|
||||||
|
Toast.makeText(getActivity(), getResources().getString(R.string.failedDuplicateQuiz), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Toast.makeText(getActivity(), android.R.string.ok, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities.congratsActivity;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mysaa
|
||||||
|
* @date on 27/07/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class CongratsActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String FRAGEN = "com.bernard.qcminator.FRAGEN";
|
||||||
|
public static final String REPLIES = "com.bernard.qcminator.REPLIES";
|
||||||
|
public static final String QUIZ_DATA = "com.bernard.qcminator.QUIZ_DATA";
|
||||||
|
|
||||||
|
QuizMetadata meta;
|
||||||
|
Frage[] fragen;
|
||||||
|
List<Frage.Reply> replies;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
//TODO check intent
|
||||||
|
meta = getIntent().getParcelableExtra(QUIZ_DATA);
|
||||||
|
Parcelable[] pfragen = getIntent().getParcelableArrayExtra(FRAGEN);
|
||||||
|
fragen = new Frage[pfragen.length];
|
||||||
|
for (int i = 0; i < pfragen.length; i++)fragen[i] = (Frage)pfragen[i];
|
||||||
|
replies = getIntent().getParcelableArrayListExtra(REPLIES);
|
||||||
|
|
||||||
|
create(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void create(@Nullable Bundle savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities.congratsActivity;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.fragen.BlocFrage;
|
||||||
|
|
||||||
|
public class DEVerbenCongratsActivity extends CongratsActivity implements View.OnClickListener{
|
||||||
|
|
||||||
|
ListView deverben;
|
||||||
|
TextView score;
|
||||||
|
Button doneButton;
|
||||||
|
DEVerbenReplyadapter adapter;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create(@Nullable Bundle savedInstanceState) {
|
||||||
|
setContentView(R.layout.activity_deverben_congrats);
|
||||||
|
deverben = findViewById(R.id.verbeLayout);
|
||||||
|
score = findViewById(R.id.noteText);
|
||||||
|
int z = 0;
|
||||||
|
for (int i = 0; i < replies.size(); i++)if(((BlocFrage.Reply) replies.get(i)).getAnswered().equals(((BlocFrage)fragen[i]).getRichtigAntwort()))z++;
|
||||||
|
score.setText(z + "/" + replies.size());
|
||||||
|
adapter = new DEVerbenReplyadapter();
|
||||||
|
deverben.setAdapter(adapter);
|
||||||
|
doneButton = findViewById(R.id.doneButton);
|
||||||
|
doneButton.setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DEVerbenReplyadapter extends BaseAdapter{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return replies.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return replies.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ViewGroup lay;
|
||||||
|
TextView text;
|
||||||
|
if(convertView == null)
|
||||||
|
lay = (ViewGroup)getLayoutInflater().inflate(R.layout.deverben_reply_row_layout,parent,false);
|
||||||
|
else
|
||||||
|
lay = (ViewGroup)convertView;
|
||||||
|
text = lay.findViewById(R.id.deverbenRepyText);
|
||||||
|
BlocFrage frage = (BlocFrage)fragen[position];
|
||||||
|
BlocFrage.Reply reply = (BlocFrage.Reply) replies.get(position);
|
||||||
|
boolean correct = reply.getAnswered().equals(frage.getRichtigAntwort());
|
||||||
|
text.setGravity(Gravity.CENTER);
|
||||||
|
if(correct){
|
||||||
|
text.setText(frage.getRichtigAntwort());
|
||||||
|
text.setBackgroundColor(getResources().getColor(R.color.goodAnswer));
|
||||||
|
}else{
|
||||||
|
text.setText(Html.fromHtml("<span style=\"text-decoration:line-through;\">" + reply.getAnswered() + "</span> -> " + frage.getRichtigAntwort()));
|
||||||
|
text.setBackgroundColor(getResources().getColor(R.color.wrongAnswer));
|
||||||
|
}
|
||||||
|
return lay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities.fragenActivities;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TableLayout;
|
||||||
|
import android.widget.TableRow;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.frageable.BlocFrageable;
|
||||||
|
import com.bernard.mcqinator.api.fragen.BlocFrage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class BlocFrageActivity extends FrageActivity<BlocFrage> implements View.OnClickListener{
|
||||||
|
|
||||||
|
TextView frage;
|
||||||
|
TableLayout tl;
|
||||||
|
Button[] buttons;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiate(BlocFrage f) {
|
||||||
|
ArrayList<String> replies = new ArrayList<>();
|
||||||
|
replies.addAll(Arrays.asList(f.getFalshAntworte()));
|
||||||
|
replies.add(f.getRichtigAntwort());
|
||||||
|
Log.d("Buttons",Arrays.toString(buttons));
|
||||||
|
for (Button button : buttons) {
|
||||||
|
int pos = (int) (Math.random() * (double) replies.size());
|
||||||
|
button.setText(replies.get(pos));
|
||||||
|
replies.remove(pos);
|
||||||
|
}
|
||||||
|
frage.setText(f.getFrage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("null")
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_bloc_frage);
|
||||||
|
|
||||||
|
BlocFrageable.BlocData data = getIntent().getParcelableExtra(QUIZ_DATA);
|
||||||
|
int bn = data.blockNumber;
|
||||||
|
|
||||||
|
frage= findViewById(R.id.frageText);
|
||||||
|
tl= findViewById(R.id.blocTable);
|
||||||
|
|
||||||
|
TableRow tr = null;
|
||||||
|
buttons = new Button[bn];
|
||||||
|
TableRow.LayoutParams params = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,TableRow.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.weight = 50;
|
||||||
|
TableLayout.LayoutParams tparams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
for(int b = 0;b<bn;b++){
|
||||||
|
if(b%2==0) {
|
||||||
|
tr = new TableRow(this);
|
||||||
|
tr.setLayoutParams(tparams);
|
||||||
|
}
|
||||||
|
Button butt = new Button(this);
|
||||||
|
butt.setLayoutParams(params);
|
||||||
|
|
||||||
|
butt.setOnClickListener(this);
|
||||||
|
buttons[b] = butt;
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
tr.addView(butt);
|
||||||
|
if(b%2==1)
|
||||||
|
tl.addView(tr);
|
||||||
|
}
|
||||||
|
if(bn%2==1)
|
||||||
|
tl.addView(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
BlocFrage.Reply reply = new BlocFrage.Reply(((TextView)v).getText().toString());
|
||||||
|
|
||||||
|
reply(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities.fragenActivities;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.api.fragen.Frage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samy
|
||||||
|
* @date on 04/05/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class FrageActivity<T extends Frage> extends Activity {
|
||||||
|
|
||||||
|
public static final String FRAGEN = "com.bernard.qcminator.FRAGEN";
|
||||||
|
public static final String REPLIES = "com.bernard.qcminator.REPLIES";
|
||||||
|
public static final String QUIZ_DATA = "com.bernard.qcminator.QUIZ_DATA";
|
||||||
|
|
||||||
|
List<T> fragen;
|
||||||
|
private List<Frage.Reply> replies;
|
||||||
|
private int currentFrage = 0;
|
||||||
|
public abstract void initiate(T f);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Parcelable[] preFragen = getIntent().getParcelableArrayExtra(FRAGEN);
|
||||||
|
fragen = new ArrayList<>();
|
||||||
|
for (Parcelable aPreFragen : preFragen) fragen.add((T) aPreFragen);
|
||||||
|
Log.v("FrageActivity","Fragen : "+fragen);
|
||||||
|
replies = new ArrayList<>();
|
||||||
|
final View rout = findViewById(android.R.id.content);
|
||||||
|
rout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
initiate(fragen.get(currentFrage));
|
||||||
|
rout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reply(Frage.Reply reply){
|
||||||
|
replies.add(reply);
|
||||||
|
|
||||||
|
currentFrage++;
|
||||||
|
if(currentFrage == fragen.size()) {
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.putParcelableArrayListExtra(REPLIES,(ArrayList<? extends Parcelable>)replies);
|
||||||
|
setResult(RESULT_OK,i);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
initiate(fragen.get(currentFrage));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.bernard.mcqinator.view.activities.fragenActivities;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.frageable.TextFrageable;
|
||||||
|
import com.bernard.mcqinator.api.fragen.TextFrage;
|
||||||
|
|
||||||
|
public class TextFrageActivity extends FrageActivity<TextFrage> implements View.OnClickListener{
|
||||||
|
|
||||||
|
TextView frage;
|
||||||
|
EditText antwort;
|
||||||
|
Button nextButton;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiate(TextFrage f) {
|
||||||
|
frage.setText(f.getFrage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("null")
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_text_frage);
|
||||||
|
|
||||||
|
TextFrageable.TextData data = getIntent().getParcelableExtra(QUIZ_DATA);
|
||||||
|
|
||||||
|
frage= findViewById(R.id.frageText);
|
||||||
|
antwort = findViewById(R.id.antwortText);
|
||||||
|
nextButton = findViewById(R.id.next);
|
||||||
|
|
||||||
|
nextButton.setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
TextFrage.Reply reply = new TextFrage.Reply(antwort.getText().toString());
|
||||||
|
|
||||||
|
reply(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
package com.bernard.mcqinator.view.quizEditing.formQuiz;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.QuizMetadata;
|
||||||
|
import com.bernard.mcqinator.api.quiz.FormQuiz;
|
||||||
|
import com.bernard.mcqinator.api.quiz.Quiz;
|
||||||
|
import com.bernard.mcqinator.controller.FileManager;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.view.activities.ChoosingQuizToEditActivity;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class EditFormQuiz extends ListActivity {
|
||||||
|
|
||||||
|
public static final int ITEM_NEW = 0x5603B6BD;
|
||||||
|
public static final int ITEM_CHANGE = 0x68E0B3A1;
|
||||||
|
|
||||||
|
QuizMetadata quizMetadata;
|
||||||
|
FormQuiz quiz;
|
||||||
|
FormQuiz.ItemAdapter adapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
Intent i = getIntent();
|
||||||
|
long fileID = i.getLongExtra(ChoosingQuizToEditActivity.QUIZ_FILEID,-1);//TODO check intent
|
||||||
|
Quiz q;
|
||||||
|
try {
|
||||||
|
quizMetadata = QuizMetadataManager.getQuiz(this,fileID);
|
||||||
|
q = FileManager.getQuiz(quizMetadata,this);
|
||||||
|
if(q == null)throw new IOException("FileManager.getQuiz returned null");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("EditingFormQuiz","Cannot instantiate the quiz or the quizmetadata",e);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quiz = (FormQuiz)q;
|
||||||
|
setContentView(quiz.getEditActivityLayoutID());
|
||||||
|
try {
|
||||||
|
Button neueItem = findViewById(R.id.neueItemButton);//TODO check button presence (not a try / catch)
|
||||||
|
neueItem.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(EditFormQuiz.this, EditFormQuizItem.class);
|
||||||
|
i.putExtra(EditFormQuizItem.TO_EDIT_ITEM, (Parcelable) null);
|
||||||
|
i.putExtra(EditFormQuizItem.QUIZ_FILEID, quizMetadata.getFileID());
|
||||||
|
startActivityForResult(i, ITEM_NEW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch(NullPointerException e){
|
||||||
|
Log.e("EditFormQuiz","The layout "+quiz.getClass().getName()+".getEditActivityLayoutID() has to own a Button with the ID 'neueItemButton'");
|
||||||
|
}catch(ClassCastException e){
|
||||||
|
Log.e("EditFormQuiz","The view 'neueItemButton' in the layout "+quiz.getClass().getName()+".getEditActivityLayoutID() has to be a Button");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Button doneButton = findViewById(R.id.doneButton);//TODO check button presence (not a try / catch)
|
||||||
|
doneButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
FileManager.saveQuiz(quizMetadata,quiz,EditFormQuiz.this);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}catch(NullPointerException e){
|
||||||
|
Log.d("EditFormQuiz","The layout "+quiz.getClass().getName()+".getEditActivityLayoutID() has to own a Button with the ID 'doneButton'");
|
||||||
|
}catch(ClassCastException e){
|
||||||
|
Log.d("EditFormQuiz","The view 'doneButton' in the layout "+quiz.getClass().getName()+".getEditActivityLayoutID() has to be a Button");
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter = quiz.new ItemAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
if(requestCode == ITEM_NEW && resultCode == RESULT_OK){
|
||||||
|
FormQuiz.Item v = data.getParcelableExtra(EditFormQuizItem.EDITED_ITEM);
|
||||||
|
quiz.addItem(v);
|
||||||
|
FileManager.saveQuiz(quizMetadata,quiz,this);
|
||||||
|
adapter = quiz.new ItemAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
}
|
||||||
|
if(requestCode == ITEM_CHANGE && resultCode == RESULT_OK){
|
||||||
|
FormQuiz.Item v = data.getParcelableExtra(EditFormQuizItem.EDITED_ITEM);
|
||||||
|
int pos = data.getIntExtra(EditFormQuizItem.ITEM_POSITION,0);
|
||||||
|
quiz.setItem(pos,v);
|
||||||
|
FileManager.saveQuiz(quizMetadata,quiz,this);
|
||||||
|
adapter = quiz.new ItemAdapter(this);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||||
|
Intent i = new Intent(EditFormQuiz.this, EditFormQuizItem.class);
|
||||||
|
i.putExtra(EditFormQuizItem.TO_EDIT_ITEM,(Parcelable)adapter.getItem(position));
|
||||||
|
i.putExtra(EditFormQuizItem.ITEM_POSITION,position);
|
||||||
|
i.putExtra(EditFormQuizItem.QUIZ_FILEID,quizMetadata.getFileID());
|
||||||
|
startActivityForResult(i,ITEM_CHANGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,162 @@
|
|||||||
|
package com.bernard.mcqinator.view.quizEditing.formQuiz;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.bernard.mcqinator.R;
|
||||||
|
import com.bernard.mcqinator.api.quiz.FormQuiz;
|
||||||
|
import com.bernard.mcqinator.controller.FileManager;
|
||||||
|
import com.bernard.mcqinator.controller.QuizMetadataManager;
|
||||||
|
import com.bernard.mcqinator.inutil.ArrayInutil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EditFormQuizItem extends Activity implements View.OnClickListener{
|
||||||
|
|
||||||
|
public static final String EDITED_ITEM = "com.bernard.qcminator.EDITED_ITEM";
|
||||||
|
public static final String QUIZ_FILEID = "com.bernard.qcminator.QUIZ_FILEID";
|
||||||
|
public static final String TO_EDIT_ITEM = "com.bernard.qcminator.TO_EDIT_ITEM";
|
||||||
|
public static final String ITEM_POSITION = "com.bernard.qcminator.ITEM_POSITION";
|
||||||
|
|
||||||
|
View[] addButtons;
|
||||||
|
ViewGroup[] formsLayout;
|
||||||
|
ViewGroup itemLayout;
|
||||||
|
List<View> falseFields;
|
||||||
|
FormQuiz quiz;
|
||||||
|
|
||||||
|
final View.OnClickListener delFalshItemOnClickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//TODO ask confirmation if editText not empty
|
||||||
|
//TODO check cast
|
||||||
|
int pos = (int)v.getTag(R.id.itemLayout);
|
||||||
|
((ViewGroup)falseFields.get(pos).getParent()).removeView(falseFields.get(pos));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
try {
|
||||||
|
quiz = (FormQuiz) FileManager.getQuiz(QuizMetadataManager.getQuiz(this,getIntent().getLongExtra(QUIZ_FILEID,0)),this);
|
||||||
|
if(quiz == null)throw new IOException("FileManager.getQuiz returned null ...");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();//TODO customize error log
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setContentView(quiz.getEditItemActivityLayoutID());
|
||||||
|
|
||||||
|
final FormQuiz.Item item = (getIntent().getParcelableExtra(TO_EDIT_ITEM)!=null)?(FormQuiz.Item)getIntent().getParcelableExtra(TO_EDIT_ITEM):new FormQuiz.Item(new FormQuiz.Item.Form[quiz.getFormCount()]);
|
||||||
|
|
||||||
|
formsLayout = new LinearLayout[item.getForms().length];
|
||||||
|
addButtons = new View[item.getForms().length];
|
||||||
|
falseFields = new ArrayList<>();
|
||||||
|
|
||||||
|
itemLayout = findViewById(R.id.itemLayout);
|
||||||
|
//TODO add exception if ids missing
|
||||||
|
for (int i = 0; i < item.getForms().length; i++) {
|
||||||
|
formsLayout[i] = (ViewGroup)getLayoutInflater().inflate(quiz.getEditItemActivityFormLayoutID(),itemLayout,false);
|
||||||
|
TextView richtig = formsLayout[i].findViewById(R.id.realItem);
|
||||||
|
richtig.setText(item.getForms()[i].getRichtig());
|
||||||
|
|
||||||
|
TextView formName = formsLayout[i].findViewById(R.id.formName);
|
||||||
|
formName.setText(quiz.getFormNameStringId(i));
|
||||||
|
|
||||||
|
View addItemButton = formsLayout[i].findViewById(R.id.addButton);
|
||||||
|
addItemButton.setOnClickListener(this);
|
||||||
|
addButtons[i] = addItemButton;
|
||||||
|
itemLayout.addView(formsLayout[i]);
|
||||||
|
|
||||||
|
for (int j = 0; j < item.getForms()[i].getFalshe().length; j++) {
|
||||||
|
View falshe = getLayoutInflater().inflate(R.layout.edit_form_quiz_item_false,formsLayout[i],false);
|
||||||
|
TextView falseField = falshe.findViewById(R.id.falshItem);
|
||||||
|
falseField.setTag(R.id.falshItem,i);
|
||||||
|
falseField.setText(item.getForms()[i].getFalshe()[j]);
|
||||||
|
View delFalseButton = falshe.findViewById(R.id.delFalshItemButton);
|
||||||
|
delFalseButton.setTag(R.id.itemLayout,falseFields.size());
|
||||||
|
delFalseButton.setOnClickListener(delFalshItemOnClickListener);
|
||||||
|
formsLayout[i].addView(falshe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button doneButton = findViewById(R.id.doneButton);//TODO check exists
|
||||||
|
doneButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Resources r = EditFormQuizItem.this.getResources();
|
||||||
|
FormQuiz.Item.Form[] forms = new FormQuiz.Item.Form[formsLayout.length];
|
||||||
|
for (int i = 0; i < item.getForms().length; i++) {
|
||||||
|
ArrayList<String> falshe = new ArrayList<>();
|
||||||
|
String realItem = ((TextView)formsLayout[i].findViewById(R.id.realItem)).getText().toString();
|
||||||
|
if(realItem.isEmpty()){
|
||||||
|
String e = r.getString(R.string.missingReal,r.getString(quiz.getFormNameStringId(i)));
|
||||||
|
Log.i("ParsingResults", e);
|
||||||
|
Toast.makeText(EditFormQuizItem.this,e,Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<View> childs = getAllChildren(formsLayout[i]);
|
||||||
|
for (View child : childs) {
|
||||||
|
if(child.getTag(R.id.falshItem) == null)
|
||||||
|
continue;
|
||||||
|
String s = ((TextView)child).getText().toString();
|
||||||
|
if(!s.isEmpty()) falshe.add(s);
|
||||||
|
}
|
||||||
|
Log.v("Configurator","FalsheAntwort : " + falshe);
|
||||||
|
String[] falsharray = new String[falshe.size()];
|
||||||
|
falshe.toArray(falsharray);
|
||||||
|
forms[i] = new FormQuiz.Item.Form((byte)0/* TODO implement formID */,realItem,falsharray);
|
||||||
|
}
|
||||||
|
|
||||||
|
FormQuiz.Item newItem = new FormQuiz.Item(forms);
|
||||||
|
Intent i = new Intent();
|
||||||
|
|
||||||
|
i.putExtra(EDITED_ITEM,(Parcelable)newItem);
|
||||||
|
|
||||||
|
setResult(RESULT_OK,i);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<View> getAllChildren(View v){
|
||||||
|
return getAllChildren(v,new ArrayList<View>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<View> getAllChildren(View v,List<View> l){
|
||||||
|
l.add(v);
|
||||||
|
if(v instanceof ViewGroup){
|
||||||
|
ViewGroup vg = (ViewGroup)v;
|
||||||
|
for (int i = 0; i < vg.getChildCount(); i++)
|
||||||
|
getAllChildren(vg.getChildAt(i),l);
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
int buttonPos = ArrayInutil.indexOf(addButtons,v);
|
||||||
|
|
||||||
|
View falshe = getLayoutInflater().inflate(R.layout.edit_form_quiz_item_false,formsLayout[buttonPos],false);
|
||||||
|
TextView falseField = falshe.findViewById(R.id.falshItem);
|
||||||
|
View delFalseButton = falshe.findViewById(R.id.delFalshItemButton);
|
||||||
|
falseField.setTag(R.id.falshItem,buttonPos);
|
||||||
|
delFalseButton.setTag(R.id.itemLayout,falseFields.size());
|
||||||
|
delFalseButton.setOnClickListener(delFalshItemOnClickListener);
|
||||||
|
falseFields.add(falshe);
|
||||||
|
formsLayout[buttonPos].addView(falshe);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
app/src/main/res/drawable-hdpi/bloc_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/drawable-hdpi/dark_tiled_background.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
app/src/main/res/drawable-hdpi/de_verben_quiz.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
app/src/main/res/drawable-hdpi/default_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 800 B |
BIN
app/src/main/res/drawable-hdpi/light_tiled_background.png
Normal file
|
After Width: | Height: | Size: 265 KiB |
BIN
app/src/main/res/drawable-hdpi/white_button_default.9.png
Normal file
|
After Width: | Height: | Size: 310 B |
BIN
app/src/main/res/drawable-hdpi/white_button_disabled.9.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
app/src/main/res/drawable-hdpi/white_button_focused.9.png
Normal file
|
After Width: | Height: | Size: 387 B |
BIN
app/src/main/res/drawable-hdpi/white_button_pressed.9.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
app/src/main/res/drawable-mdpi/bloc_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/main/res/drawable-mdpi/dark_tiled_background.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
app/src/main/res/drawable-mdpi/de_verben_quiz.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable-mdpi/default_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 509 B |
BIN
app/src/main/res/drawable-mdpi/light_tiled_background.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
app/src/main/res/drawable-mdpi/white_button_default.9.png
Normal file
|
After Width: | Height: | Size: 244 B |
BIN
app/src/main/res/drawable-mdpi/white_button_disabled.9.png
Normal file
|
After Width: | Height: | Size: 163 B |
BIN
app/src/main/res/drawable-mdpi/white_button_focused.9.png
Normal file
|
After Width: | Height: | Size: 325 B |
BIN
app/src/main/res/drawable-mdpi/white_button_pressed.9.png
Normal file
|
After Width: | Height: | Size: 246 B |
34
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable-xhdpi/bloc_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/dark_tiled_background.png
Normal file
|
After Width: | Height: | Size: 251 KiB |
BIN
app/src/main/res/drawable-xhdpi/de_verben_quiz.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/default_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/drawable-xhdpi/light_tiled_background.png
Normal file
|
After Width: | Height: | Size: 488 KiB |
BIN
app/src/main/res/drawable-xhdpi/white_button_default.9.png
Normal file
|
After Width: | Height: | Size: 429 B |
BIN
app/src/main/res/drawable-xhdpi/white_button_disabled.9.png
Normal file
|
After Width: | Height: | Size: 267 B |
BIN
app/src/main/res/drawable-xhdpi/white_button_focused.9.png
Normal file
|
After Width: | Height: | Size: 538 B |
BIN
app/src/main/res/drawable-xhdpi/white_button_pressed.9.png
Normal file
|
After Width: | Height: | Size: 418 B |
BIN
app/src/main/res/drawable-xxhdpi/bloc_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xxhdpi/dark_tiled_background.png
Normal file
|
After Width: | Height: | Size: 376 KiB |
BIN
app/src/main/res/drawable-xxhdpi/de_verben_quiz.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable-xxhdpi/default_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xxhdpi/light_tiled_background.png
Normal file
|
After Width: | Height: | Size: 755 KiB |
BIN
app/src/main/res/drawable-xxhdpi/white_button_default.9.png
Normal file
|
After Width: | Height: | Size: 540 B |
BIN
app/src/main/res/drawable-xxhdpi/white_button_disabled.9.png
Normal file
|
After Width: | Height: | Size: 393 B |
BIN
app/src/main/res/drawable-xxhdpi/white_button_focused.9.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
app/src/main/res/drawable-xxhdpi/white_button_pressed.9.png
Normal file
|
After Width: | Height: | Size: 533 B |
BIN
app/src/main/res/drawable-xxxhdpi/bloc_quiz_icon.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/dark_tiled_background.png
Normal file
|
After Width: | Height: | Size: 546 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/de_verben_quiz.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/light_tiled_background.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
app/src/main/res/drawable-xxxhdpi/white_button_default.9.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/white_button_disabled.9.png
Normal file
|
After Width: | Height: | Size: 606 B |
BIN
app/src/main/res/drawable-xxxhdpi/white_button_focused.9.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/white_button_pressed.9.png
Normal file
|
After Width: | Height: | Size: 965 B |
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#008577"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
14
app/src/main/res/drawable/white_button.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:drawable="@drawable/white_button_pressed"
|
||||||
|
android:state_pressed="true" />
|
||||||
|
<item android:drawable="@drawable/white_button_focused"
|
||||||
|
android:state_focused="true" />
|
||||||
|
<item android:drawable="@drawable/white_button_default"
|
||||||
|
android:state_enabled="false" >
|
||||||
|
<color android:color="@color/disabledButtonText" />
|
||||||
|
</item>
|
||||||
|
<item android:drawable="@drawable/white_button_default" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
22
app/src/main/res/layout/activity_bloc_frage.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".view.activities.fragenActivities.BlocFrageActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight=".50"
|
||||||
|
android:id="@+id/frageText"/>
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight=".50"
|
||||||
|
android:id="@+id/blocTable">
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
27
app/src/main/res/layout/activity_choosing_quiz.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.ChoosingQuizActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/chooseYourQuiz"
|
||||||
|
android:id="@+id/chooseQuizText"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/chooseQuizText"
|
||||||
|
android:id="@android:id/list"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@android:id/list"
|
||||||
|
android:text="@string/noQuiz"
|
||||||
|
android:id="@android:id/empty" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
36
app/src/main/res/layout/activity_choosing_quiz_to_edit.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.ChoosingQuizActivity">
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/newQuiz"
|
||||||
|
android:id="@+id/newQuizButton"
|
||||||
|
android:layout_alignParentBottom="true"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/chooseYourQuiz"
|
||||||
|
android:id="@+id/chooseQuizText"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/chooseQuizText"
|
||||||
|
android:layout_above="@id/newQuizButton"
|
||||||
|
android:id="@android:id/list"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@android:id/list"
|
||||||
|
android:text="@string/noQuiz"
|
||||||
|
android:id="@android:id/empty" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
43
app/src/main/res/layout/activity_configuring_quiz.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:weightSum="100"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.ConfiguringQuizActivity">
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/done"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:id="@+id/doneButton"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_above="@id/doneButton"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:divider="?android:dividerHorizontal"
|
||||||
|
android:showDividers="middle">
|
||||||
|
<ListView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight=".70"
|
||||||
|
android:id="@android:id/list">
|
||||||
|
|
||||||
|
</ListView>
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight=".30">
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/attributesFrame">
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
132
app/src/main/res/layout/activity_create_quiz.xml
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.CreateQuizActivity">
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="5sp"
|
||||||
|
android:id="@+id/quizNameAskLayout"
|
||||||
|
android:layout_alignParentTop="true">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/quizNameAsk"
|
||||||
|
android:id="@+id/quizNameAskText"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:textAppearance="@style/LightFormText"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/quizNameAsk"
|
||||||
|
android:layout_toEndOf="@id/quizNameAskText"
|
||||||
|
android:inputType="text"
|
||||||
|
android:layout_toRightOf="@id/quizNameAskText"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true" />
|
||||||
|
</RelativeLayout>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="5sp"
|
||||||
|
android:id="@+id/quizAuthorAskLayout"
|
||||||
|
android:layout_below="@id/quizNameAskLayout">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/quizAuthorAsk"
|
||||||
|
android:id="@+id/quizAuthorAskText"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:textAppearance="@style/LightFormText"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/quizAuthorAsk"
|
||||||
|
android:layout_toEndOf="@id/quizAuthorAskText"
|
||||||
|
android:inputType="text"
|
||||||
|
android:layout_toRightOf="@id/quizAuthorAskText"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true" />
|
||||||
|
</RelativeLayout>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="5sp"
|
||||||
|
android:id="@+id/quizTypeAskLayout"
|
||||||
|
android:layout_below="@id/quizAuthorAskLayout">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/quizTypeAsk"
|
||||||
|
android:id="@+id/quizTypeAskText"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:textAppearance="@style/LightFormText"/>
|
||||||
|
<Spinner
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/quizTypeAsk"
|
||||||
|
android:layout_toEndOf="@id/quizTypeAskText"
|
||||||
|
android:layout_toRightOf="@id/quizTypeAskText"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:entries="@array/randomWorte"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:id="@+id/doneButton"
|
||||||
|
android:text="@string/newQuiz"/>
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="top"
|
||||||
|
android:padding="5sp"
|
||||||
|
android:layout_below="@id/quizTypeAskLayout"
|
||||||
|
android:layout_above="@id/doneButton">
|
||||||
|
<CheckBox
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/quizHasParentAsk"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentLeft="true"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/quizParentAsk"
|
||||||
|
android:id="@+id/quizParentAskText"
|
||||||
|
android:layout_toEndOf="@id/quizHasParentAsk"
|
||||||
|
android:layout_toRightOf="@id/quizHasParentAsk"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:textAppearance="@style/LightFormText"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/noQuiz"
|
||||||
|
android:id="@+id/quizParentAskNoQuiz"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
android:gravity="start"
|
||||||
|
android:layout_below="@id/quizParentAskText"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:textAppearance="@style/LightFormText"/>
|
||||||
|
<ListView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/quizParentChoose"
|
||||||
|
android:layout_below="@id/quizParentAskText"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:entries="@array/randomWorte"/>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
41
app/src/main/res/layout/activity_deverben_congrats.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.congratsActivity.DEVerbenCongratsActivity">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:id="@+id/textLayout">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/noteText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/wait"
|
||||||
|
android:textColor="@color/colorAccent"
|
||||||
|
android:textSize="50sp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:id="@id/doneButton"
|
||||||
|
android:text="@android:string/ok"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/verbeLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignWithParentIfMissing="false"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_above="@+id/doneButton"
|
||||||
|
android:layout_below="@+id/textLayout" />
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
43
app/src/main/res/layout/activity_edit_quiz_deverben.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.quizEditing.formQuiz.EditFormQuiz">
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/doneButton"
|
||||||
|
android:text="@string/done"
|
||||||
|
android:layout_alignParentBottom="true"/>
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/neueItemButton"
|
||||||
|
android:text="@string/neueVerbe"
|
||||||
|
android:layout_above="@id/doneButton"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/selectVerbeToEdit"
|
||||||
|
android:id="@+id/selectItemToEditText"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:gravity="center_horizontal"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_below="@id/selectItemToEditText"
|
||||||
|
android:layout_above="@id/neueItemButton" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/noVerbeToEdit"
|
||||||
|
android:id="@android:id/empty"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_below="@id/selectItemToEditText"
|
||||||
|
android:layout_above="@id/neueItemButton"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
62
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.MainActivity">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/takeQuiz"
|
||||||
|
android:id="@+id/takeQuizButton"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/manageMyQuiz"
|
||||||
|
android:id="@+id/manageMyQuizButton"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/createQuiz"
|
||||||
|
android:id="@+id/createQuizButton"
|
||||||
|
android:enabled="false"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/options"
|
||||||
|
android:id="@+id/optionsButton"/>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/loading"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:background="@android:drawable/screen_background_dark_transparent"
|
||||||
|
android:indeterminate="true" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
34
app/src/main/res/layout/activity_quiz_manager.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.bernard.mcqinator.view.activities.QuizManagerActivity">
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="20dp"
|
||||||
|
android:text="@string/importQuiz"
|
||||||
|
android:id="@+id/importQuiz"
|
||||||
|
android:layout_alignParentBottom="true"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/selectQuizToManage"
|
||||||
|
android:id="@+id/selectQuizToManageText"/>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/selectQuizToManageText"
|
||||||
|
android:layout_above="@id/importQuiz"
|
||||||
|
android:id="@android:id/list"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@android:id/list"
|
||||||
|
android:text="@string/noQuiz"
|
||||||
|
android:id="@android:id/empty" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
30
app/src/main/res/layout/activity_text_frage.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".view.activities.fragenActivities.BlocFrageActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:id="@+id/frageText"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:id="@+id/antwortText"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:text="@android:string/ok"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:id="@+id/next"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
24
app/src/main/res/layout/bloc_frage_options_layout.xml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<Button
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/blocPerFrage"
|
||||||
|
android:id="@+id/blocCount"
|
||||||
|
android:longClickable="true"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/fragCount"
|
||||||
|
android:id="@+id/frageCountText"
|
||||||
|
android:longClickable="true"/>
|
||||||
|
<SeekBar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="50"
|
||||||
|
android:id="@+id/frageCount"
|
||||||
|
android:longClickable="true"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||