Compare commits

..

No commits in common. "master" and "v1.1" have entirely different histories.
master ... v1.1

31 changed files with 526 additions and 946 deletions

View file

@ -1,233 +1,198 @@
using HtmlAgilityPack;
using Orarend.Events;
using SimpleTimerPortable;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Security;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Orarend
{
[DataContract]
public class API
{ //TODO: Előre megadott egyedi nevek használata
internal static API példány = new API(); //TODO: FrissítésHa1ÓraEltelt() mentés
private API()
{
}
/// <summary>
/// A kulcs az óra azonosítója
/// </summary>
[DataMember(Order = 1)]
public Dictionary<string, ÓraTípus> típusok { get; private set; } = new Dictionary<string, ÓraTípus>();
[DataMember]
public Osztály[] osztályok { get; private set; } = new Osztály[0]; //Ez az initializáció csak akkor fut le, ha nem tölti be fájlból
[DataMember(Order = 2)]
public List<Órarend> órarendek { get; private set; } = new List<Órarend>();
[DataMember(Order = 3)]
public Settings beállítások { get; private set; } = new Settings();
public static class API
{ //TODO: Beállítások: Téma (sötét, világos) (Android; platformfüggő beállítások), Előre megadott egyedi nevek használata
/// <summary>
/// <para>Visszatér az osztályok listájával.</para>
/// <para>Lehet null, ha még nem volt sikeres <see cref="Frissítés"/>.</para>
/// </summary>
/// <returns></returns>
public static Osztály[] Osztályok { get => példány.osztályok; private set => példány.osztályok = value; }
public static List<Órarend> Órarendek { get { return példány.órarendek; } }
public static Settings Beállítások { get => példány.beállítások; private set => példány.beállítások = value; }
public static Osztály[] Osztályok { get; private set; }
public static List<Órarend> Órarendek { get; } = new List<Órarend>();
public static Settings Beállítások { get; private set; } = new Settings();
/// <summary>
/// Frissíti az osztálylistát és az eredeti órarendet, első megnyitásnál, és egy órarend hozzáadásánál/szerkesztésénél, majd hetente elegendő meghívni
/// <param name="stream">A file stream, ahova mentse az adatokat, hogy ne kelljen külön meghívni - Azért funkció, hogy elkerüljök az adatvesztést, mivel így csak a mentéskor nyitja meg</param>
/// <param name="órarendstream">A file stream, ahova mentse az adatokat, hogy ne kelljen külön meghívni - Azért funkció, hogy elkerüljök az adatvesztést, mivel így csak a mentéskor nyitja meg</param>
/// <param name="osztálystream">A file stream, ahova mentse az adatokat, hogy ne kelljen külön meghívni - Azért funkció, hogy elkerüljök az adatvesztést, mivel így csak a mentéskor nyitja meg</param>
/// </summary>
public static async Task Frissítés(Func<Stream> stream, Órarend ór = null)
public static async Task Frissítés(Func<Stream> órarendstream, Func<Stream> osztálystream, Órarend ór = null)
{
Func<string, Task<HtmlDocument>> load = async (url) =>
try
{
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp(url);
var resp = await req.GetResponseAsync();
await Task.Run(() =>
Func<string, Task<HtmlDocument>> load = async (url) =>
{
using (var sr = new StreamReader(resp.GetResponseStream()))
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp(url);
var resp = await req.GetResponseAsync();
await Task.Run(() =>
{
const string trtd = @"(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>(?!.+?\<table(?:\s\w+?=\""?\w+\""?)*\>.+?)(.+?)(?=<\1(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>)";
string html = Regex.Replace(Regex.Replace(Regex.Replace(sr.ReadToEnd(), "<th([^>]*)>((?:\\w|[áéóüöőúű./])+)(?=<)(?!\\/)", "<th$1>$2</th>"), "<(tr)" + trtd, "<$1>$2</$1>"), "<(td)" + trtd, "<$1>$2</$1>");
doc.LoadHtml(html);
}
});
return doc;
};
if (Órarendek.Count == 0)
{
var doc = await load("http://deri.enaplo.net/ajax/orarend/orarendoszt.php");
await Task.Run(() => Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new Osztály { Azonosító = node.GetAttributeValue("value", ""), Név = node.NextSibling.InnerText }).ToArray());
}
Func<Órarend, Task> órarenda = async órarend =>
{
var doc = await load("https://deri.enaplo.net/ajax/orarend/orarendoszt.php?p=" + órarend.Osztály.Azonosító);
await Task.Run(() =>
{
lock (Órarendek)
using (var sr = new StreamReader(resp.GetResponseStream()))
{
const string trtd = @"(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>(?!.+?\<table(?:\s\w+?=\""?\w+\""?)*\>.+?)(.+?)(?=<\1(?:\s\w+=(?:\""|\')?(?:\w|[áéóüöőúű.:;])+(?:\""|\')?)*>)";
string html = Regex.Replace(Regex.Replace(Regex.Replace(sr.ReadToEnd(), "<th([^>]*)>((?:\\w|[áéóüöőúű.])+)(?=<)(?!\\/)", "<th$1>$2</th>"), "<(tr)" + trtd, "<$1>$2</$1>"), "<(td)" + trtd, "<$1>$2</$1>");
doc.LoadHtml(html);
}
});
return doc;
};
if (Órarendek.Count == 0)
{
var doc = await load("http://deri.enaplo.net/ajax/orarend/orarendoszt.php");
await Task.Run(() => Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new Osztály { Azonosító = node.GetAttributeValue("value", ""), Név = node.NextSibling.InnerText }).ToArray());
}
Func<Órarend, Task> órarenda = async órarend =>
{
var doc = await load("http://deri.enaplo.net/ajax/orarend/orarendoszt.php?p=" + Uri.EscapeDataString(órarend.Osztály.Azonosító));
await Task.Run(() =>
{
Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new Osztály { Azonosító = node.GetAttributeValue("value", ""), Név = node.NextSibling.InnerText }).ToArray();
bool ahét = true;
int maxx = 0;
foreach (var node in doc.GetElementbyId("oda").FirstChild.FirstChild.ChildNodes[1].ChildNodes)
lock (Órarendek)
{
switch (node.FirstChild.InnerText)
Osztályok = doc.GetElementbyId("uok").ChildNodes.Where(node => node.HasAttributes).Select(node => new Osztály { Azonosító = node.GetAttributeValue("value", ""), Név = node.NextSibling.InnerText }).ToArray();
bool ahét = true;
foreach (var node in doc.GetElementbyId("oda").FirstChild.FirstChild.ChildNodes[1].ChildNodes)
{
case "A":
ahét = true;
break;
case "B":
ahét = false;
break;
default:
{
int x = int.Parse(node.FirstChild.InnerText) - 1, y = x - Beállítások.ÓraOffset;
maxx = x > maxx ? x : maxx;
if (y >= 0 && y < órarend.Órakezdetek.Length)
órarend.Órakezdetek[y] = TimeSpan.Parse(node.FirstChild.Attributes["title"].Value.Split('-')[0].Trim());
var órák = ahét ? órarend.ÓrákAHét : órarend.ÓrákBHét;
for (int i = 0; i < 5; i++) //Napok
{
var óranode = node.ChildNodes[i + 1].FirstChild;
var óra = órák[i][x];
if (óranode.ChildNodes.Count == 0)
{
órák[i][x] = null;
continue;
}
for (int j = 0; j < óranode.ChildNodes.Count; j += 6)
{
var csoport = óranode.ChildNodes[j].InnerText.TrimEnd(':');
if (csoport != "Egész osztály" && !órarend.Csoportok.Contains(csoport))
{
órák[i][x] = null;
continue;
}
if (óra == null)
órák[i][x] = óra = new Óra();
óra.Csoportok = new string[] { csoport }; //Az állandó órarendben osztályonként csak egy csoport van egy órán
óra.Azonosító = óranode.ChildNodes[j + 2].InnerText;
óra.TeljesNév = óranode.ChildNodes[j + 2].Attributes["title"].Value;
óra.Terem = óranode.ChildNodes[j + 3].InnerText.Trim(' ', '(', ')');
óra.Tanár = new Tanár
{
Azonosító = óranode.ChildNodes[j + 4].InnerText,
Név = óranode.ChildNodes[j + 4].Attributes["title"].Value
};
break;
}
}
switch (node.FirstChild.InnerText)
{
case "A":
ahét = true;
break;
}
case "B":
ahét = false;
break;
default:
{
int x = int.Parse(node.FirstChild.InnerText) - 1;
órarend.Órakezdetek[x] = TimeSpan.Parse(node.FirstChild.Attributes["title"].Value.Split('-')[0].Trim());
for (int i = 0; i < 5; i++) //Napok
{
var óranode = node.ChildNodes[i + 1].FirstChild;
var óra = (ahét ? órarend.ÓrákAHét : órarend.ÓrákBHét)[i][x];
if (óranode.ChildNodes.Count == 0)
continue;
for (int j = 0; j < óranode.ChildNodes.Count; j += 6)
{
var csoport = óranode.ChildNodes[j].InnerText.TrimEnd(':');
if (csoport != "Egész osztály" && !órarend.Csoportok.Contains(csoport))
{
órarend.Órák[i][x] = null;
continue;
}
if (óra == null)
(ahét ? órarend.ÓrákAHét : órarend.ÓrákBHét)[i][x] = óra = new Óra();
óra.Csoportok = new string[] { csoport }; //Az állandó órarendben osztályonként csak egy csoport van egy órán
óra.Azonosító = óranode.ChildNodes[j + 2].InnerText;
óra.TeljesNév = óranode.ChildNodes[j + 2].Attributes["title"].Value;
óra.Terem = óranode.ChildNodes[j + 3].InnerText.Trim(' ', '(', ')');
óra.Tanár = new Tanár
{
Azonosító = óranode.ChildNodes[j + 4].InnerText,
Név = óranode.ChildNodes[j + 4].Attributes["title"].Value
};
break;
}
}
break;
}
}
}
Java.Lang.Thread.Sleep(10);
}
for (int i = maxx + 1; i < 16; i++) //Órák
for (int j = 0; j < 5; j++) //Napok
órarend.Órák[j][i] = null; //Kitörli a küldött órarendben nem szereplő órákat
}
});
await Task.Delay(10);
};
if (ór == null)
foreach (var órarend in Órarendek)
await órarenda(órarend);
else
await órarenda(ór);
Mentés(stream());
});
};
if (ór == null)
foreach (var órarend in Órarendek)
await órarenda(órarend);
else
await órarenda(ór);
}
finally
{
ÓrarendMentés(órarendstream());
OsztályMentés(osztálystream());
}
}
/// <summary>
/// Frissíti a helyettesítéseket, naponta, indításkor vagy gombnyommásra frissítse (minden nap az első előtérbe kerüléskor)
/// <param name="órarendstream">A file stream, ahova mentse az ÓRARENDEKET, hogy ne kelljen külön meghívni - Azért funkció, hogy elkerüljök az adatvesztést, mivel így csak a mentéskor nyitja meg</param>
/// </summary>
/// <param name="stream">A file stream, ahova mentse az adatokat, hogy ne kelljen külön meghívni - Azért funkció, hogy elkerüljök az adatvesztést, mivel így csak a mentéskor nyitja meg</param>
public static async Task<bool> HelyettesítésFrissítés(Func<Stream> stream)
public static async Task HelyettesítésFrissítés(Func<Stream> órarendstream)
{
if (Órarendek.Count == 0 || Osztályok.Length == 0)
return false;
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp("http://deri.enaplo.net/ajax/print/htlista.php");
var resp = await req.GetResponseAsync();
await Task.Run(() =>
return;
try
{
lock (Órarendek)
HtmlDocument doc = new HtmlDocument();
var req = WebRequest.CreateHttp("http://deri.enaplo.net/ajax/print/htlista.php");
var resp = await req.GetResponseAsync();
await Task.Run(() =>
{
using (var sr = new StreamReader(resp.GetResponseStream()))
doc.LoadHtml(sr.ReadToEnd());
foreach (var órarend in Órarendek)
órarend.Helyettesítések.Clear();
foreach (var node in doc.DocumentNode.ChildNodes[2].ChildNodes[1].ChildNodes)
lock (Órarendek)
{
DateTime dátum = DateTime.Parse(node.ChildNodes[0].InnerText.Substring(0, node.ChildNodes[0].InnerText.Length - 4));
int hét = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dátum, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
if (hét != Hét)
continue;
byte óraszám = byte.Parse(node.ChildNodes[1].InnerText);
var osztályok = node.ChildNodes[2].InnerText.Split(new string[] { ", " }, StringSplitOptions.None);
foreach (string osztálynév in osztályok)
using (var sr = new StreamReader(resp.GetResponseStream()))
doc.LoadHtml(sr.ReadToEnd());
foreach (var órarend in Órarendek)
órarend.Helyettesítések.Clear();
foreach (var node in doc.DocumentNode.ChildNodes[2].ChildNodes[1].ChildNodes)
{
Osztály osztály = Osztályok.SingleOrDefault(o => o.Azonosító.Contains(osztálynév));
if (osztály == null)
DateTime dátum = DateTime.Parse(node.ChildNodes[0].InnerText.Substring(0, node.ChildNodes[0].InnerText.Length - 4));
int hét = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dátum, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
if (hét != Hét)
continue;
byte óraszám = byte.Parse(node.ChildNodes[1].InnerText);
var osztályok = node.ChildNodes[2].InnerText.Split(new string[] { ", " }, StringSplitOptions.None);
foreach (string osztálynév in osztályok)
{
var x = new InvalidOperationException($"A helyettesítésekben szereplő osztály \"{osztálynév}\" nem található.");
x.Data.Add("OERROR", "CLS_NOT_FOUND");
throw x;
}
var csoportok = node.ChildNodes[3].InnerText;
int névindex = csoportok.IndexOf(osztálynév);
int végeindex = csoportok.IndexOf(")", névindex >= 0 ? névindex : 0);
string csoport = osztályok.Length == 1 ? csoportok : csoportok.Substring(névindex + osztálynév.Length + 1, végeindex - névindex - osztálynév.Length - 1);
string óraaz = node.ChildNodes[4].InnerText;
string terem = node.ChildNodes[5].InnerText.Split(new string[] { " -> " }, StringSplitOptions.None).Last(); //Mindig az új termet tárolja el, ha változott
string tanár = node.ChildNodes[7].InnerText;
string[] megj = node.ChildNodes[8].InnerText.Split(' ');
string óranév = node.ChildNodes[9].InnerText;
DayOfWeek újnap = dátum.DayOfWeek;
byte újsorszám = óraszám;
if (megj.Length > 2)
{
újnap = DateTime.Parse(megj[1]).DayOfWeek;
újsorszám = byte.Parse(megj[3].Trim('.'));
}
foreach (var órarend in (csoport == "Egész osztály" ? Órarendek : Órarendek.Where(ór => ór.Csoportok.Contains(csoport))).Where(ór => ór.Osztály == osztály))
{
if (tanár == "")
tanár = órarend.Órák[(int)dátum.DayOfWeek - 1][óraszám - 1]?.Tanár.Név ?? "";
var helyettesítés = new Helyettesítés { EredetiNap = dátum.DayOfWeek, EredetiSorszám = óraszám, ÚjÓra = tanár == "elmarad" ? null : new Óra { Azonosító = óraaz, Csoportok = new string[] { csoport }, Terem = terem, Tanár = new Tanár { Név = tanár }, TeljesNév = óranév }, ÚjNap = újnap, ÚjSorszám = újsorszám };
órarend.Helyettesítések.Add(helyettesítés);
Osztály osztály = Osztályok.Single(o => o.Azonosító.Contains(osztálynév));
var csoportok = node.ChildNodes[3].InnerText;
int névindex= csoportok.IndexOf(osztálynév);
int végeindex = csoportok.IndexOf(")", névindex >= 0 ? névindex : 0);
string csoport = osztályok.Length == 1 ? csoportok : csoportok.Substring(névindex + osztálynév.Length + 1, végeindex - névindex - osztálynév.Length - 1);
string óraaz = node.ChildNodes[4].InnerText;
string terem = node.ChildNodes[5].InnerText.Split(new string[] { " -> " }, StringSplitOptions.None).Last(); //Mindig az új termet tárolja el, ha változott
string tanár = node.ChildNodes[7].InnerText;
string[] megj = node.ChildNodes[8].InnerText.Split(' ');
string óranév = node.ChildNodes[9].InnerText;
DayOfWeek újnap = dátum.DayOfWeek;
byte újsorszám = óraszám;
if (megj.Length > 2)
{
újnap = DateTime.Parse(megj[1]).DayOfWeek;
újsorszám = byte.Parse(megj[3].Trim('.'));
}
foreach (var órarend in (csoport == "Egész osztály" ? Órarendek : Órarendek.Where(ór => ór.Csoportok.Contains(csoport))).Where(ór => ór.Osztály == osztály))
{
if (tanár == "")
tanár = órarend.Órák[(int)dátum.DayOfWeek - 1][óraszám - 1]?.Tanár.Név ?? "";
var helyettesítés = new Helyettesítés { EredetiNap = dátum.DayOfWeek, EredetiSorszám = óraszám, ÚjÓra = tanár == "elmarad" ? null : new Óra { Azonosító = óraaz, Csoportok = new string[] { csoport }, Terem = terem, Tanár = new Tanár { Név = tanár }, TeljesNév = óranév }, ÚjNap = újnap, ÚjSorszám = újsorszám };
órarend.Helyettesítések.Add(helyettesítés);
}
}
}
}
}
Mentés(stream());
utolsófrissítésplusz1óra = DateTime.Now + new TimeSpan(1, 0, 0); //Mindenképpen állítsa be, hogy ne írja folyamatosan a hibát
});
return true;
});
}
finally
{
ÓrarendMentés(órarendstream());
}
}
[OnDeserializing]
private void betöltés(StreamingContext context) => példány = this; //Az órák azonosítójának beállításakor szükséges már
/// <summary>
/// Betölti az adatokat, ha még nincsenek betöltve
/// </summary>
/// <param name="s">A stream, ahonnan betöltse az adatokat</param>
/// <param name="hibánál">Megadja, mi történjen egy hiba esetén</param>
/// <returns>Elvégezte-e a betöltést</returns>
public static bool Betöltés(Stream s, Action<Exception> hibánál)
private static T betöltés<T>(Stream s, Action<Exception> hibánál)
{
using (s)
{
if (!!!betöltés())
return false;
using (var ms = new MemoryStream())
{
s.CopyTo(ms);
@ -236,48 +201,61 @@ namespace Orarend
try
{
ms.Seek(0, SeekOrigin.Begin);
var serializer = new DataContractJsonSerializer(typeof(API));
serializer.ReadObject(ms); //A példányt beállítja, mikor elkezdi, nem várja meg, hogy végezzen (betöltés())
return true;
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(ms);
}
catch (Exception e)
{
hibánál(e);
return Betöltés();
}
}
else return false;
return default(T);
}
}
}
public static void ÓrarendBetöltés(Stream s, Action<Exception> hibánál)
{
Órarendek.AddRange(betöltés<Órarend[]>(s, hibánál) ?? new Órarend[0]);
}
public static void OsztályBetöltés(Stream s, Action<Exception> hibánál)
{
Osztályok = betöltés<Osztály[]>(s, hibánál) ?? new Osztály[0];
}
public static void BeállításBetöltés(Stream s, Action<Exception> hibánál)
{
Beállítások = betöltés<Settings>(s, hibánál);
} //TODO: Tényleges órarendből állapítsa meg azt is, hogyha egyáltalán nincs ott egy óra, és máshol sincs, és ezt írja ki
/// <summary>
/// Betölti az alapértelemzett értékeket
/// <returns>Elvégezte-e a betöltést</returns>
/// </summary>
public static bool Betöltés()
{
if (!betöltés())
return false;
példány = new API();
return true;
}
private static Timer timer;
private static bool betöltés()
{
if (!!(Órarendek.Count > 0 || Osztályok?.Length > 0 || timer != null))
return false;
timer = new Timer(CsengőTimer, null, new TimeSpan(0, 0, 0, 0, 100), new TimeSpan(0, 0, 5));
return true;
}
public static void Mentés(Stream s)
private static void mentés<T>(Stream s, T obj)
{
using (s)
if (példány != null)
new DataContractJsonSerializer(példány.GetType()).WriteObject(s, példány);
{
if (obj != null)
{
var serializer = new DataContractJsonSerializer(typeof(T));
serializer.WriteObject(s, obj);
}
}
}
public static void ÓrarendMentés(Stream s)
{
mentés(s, Órarendek.ToArray());
}
private static void OsztályMentés(Stream s)
{
mentés(s, Osztályok);
}
public static void BeállításMentés(Stream s)
{
mentés(s, Beállítások);
}
/// <summary>
/// Visszatér a megjelenítendő héttel. Ez megegyezik a tényleges héttel, kivéve hétvégén, amikor a következő
/// </summary>
@ -285,109 +263,19 @@ namespace Orarend
{
get
{
int jelenlegihét = napbólhét(DateTime.Today);
int jelenlegihét = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(DateTime.Today, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
if (DateTime.Today.DayOfWeek > DayOfWeek.Friday || DateTime.Today.DayOfWeek == DayOfWeek.Sunday)
jelenlegihét++;
return jelenlegihét;
}
}
private static int napbólhét(DateTime nap) => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(nap, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
public static bool AHét { get => Hét % 2 == napbólhét(new DateTime(DateTime.Today.Year - (DateTime.Today.Month < 8 ? 1 : 0), 9, 1)) % 2; }
public static bool Fókusz
{
set
{
if (value)
{
timer = timer.Change(new TimeSpan(0, 0, 0), new TimeSpan(0, 0, 5));
frissítésHa1ÓraEltelt();
}
else
timer.Cancel();
}
}
private static DateTime utolsófrissítésplusz1óra = DateTime.MinValue;
public static event EventHandler<FrissítésEventArgs> Frissítéskor;
public class FrissítésEventArgs : EventArgs { public bool Siker { get; set; } = false; }
private static void frissítésHa1ÓraEltelt()
{
if (utolsófrissítésplusz1óra > DateTime.Now)
return;
var args = new FrissítésEventArgs();
Frissítéskor?.Invoke(példány, args);
if (args.Siker)
utolsófrissítésplusz1óra = DateTime.Now + new TimeSpan(1, 0, 0);
}
public static DayOfWeek MaiNap
public static bool AHét
{
get
{
var x = DateTime.Today.DayOfWeek;
if (nincstöbbóra) x++;
return x > DayOfWeek.Saturday || x == DayOfWeek.Sunday ? DayOfWeek.Monday : x;
return Hét % 2 == 0;
}
}
public static (Helyettesítés innen, Helyettesítés ide) HelyettesítésInnenIde(Órarend órarend, int i, int j) =>
(órarend.Helyettesítések.FirstOrDefault(h => (int)h.EredetiNap == i + 1 && h.EredetiSorszám == j + 1),
órarend.Helyettesítések.FirstOrDefault(h => (int)h.ÚjNap == i + 1 && h.ÚjSorszám == j + 1 && h.ÚjÓra != null));
//Ha az eredeti óra elmarad, és ide lesz helyezve egy másik, az áthelyezést mutassa
public static Órarend Órarend { get; private set; }
public static void ÓrarendKiválasztás(int position) { Órarend = Órarendek[position]; CsengőTimer(null); }
public static void ÓrarendKiválasztásTörlése() { Órarend = null; CsengőTimer(null); }
private static bool nincstöbbóra = false;
public static event EventHandler<TimerEventArgs> CsengőTimerEvent;
private static void CsengőTimer(object state) => CsengőTimerEvent?.Invoke(példány, CsengőTimer());
private static TimerEventArgs CsengőTimer()
{
if (Órarend == null)
return new TimerEventArgs(null, "Nincs órarend kiválasztva");
var most = DateTime.Now - DateTime.Today;
//var most = new TimeSpan(12, 46, 0);
bool talált = false;
if (Órarend.Órakezdetek[Beállítások.ÓraOffset] == TimeSpan.Zero) //Még nincsenek beállítva a kezdetek
return new TimerEventArgs(null, "Betöltés");
string kezdveg = null, kovora = null;
for (int i = 0; i < Órarend.Órakezdetek.Length - 1; i++)
{
var vége = Órarend.Órakezdetek[i].Add(new TimeSpan(0, 45, 0));
bool becsengetés;
int x = (int)DateTime.Today.DayOfWeek - 1;
Óra óra;
var (innen, ide) = HelyettesítésInnenIde(Órarend, x, i);
Func<TimeSpan, string> óraperc = ts => ts.Hours > 0 ? ts.ToString("h\\ómm\\p") : ts.ToString("%m") + " perc";
if (x != -1 && x < 6 && (óra = ide != null ? ide.ÚjÓra : innen != null ? innen.EredetiNap != innen.ÚjNap || innen.EredetiSorszám != innen.ÚjSorszám ? null : innen.ÚjÓra : Órarend.Órák[x][i]) != null)
{ //-1: Vasárnap
if (most > Órarend.Órakezdetek[i])
{
if (most < vége)
{
kezdveg = "Kicsengetés: " + óraperc(vége - most);
talált = true;
becsengetés = false;
}
else
continue;
}
else
{
kezdveg = "Becsengetés: " + óraperc(Órarend.Órakezdetek[i] - most);
talált = true;
becsengetés = true;
}
kovora = (becsengetés ? "Következő" : "Jelenlegi") + " óra: " + óra.EgyediNév + "\n" + óra.Terem + "\n" + óra.Tanár.Név + "\n" + óra.Csoportok.Aggregate((a, b) => a + ", " + b);
break;
}
}
nincstöbbóra = !talált;
return new TimerEventArgs(kovora, kezdveg);
}
}
}

View file

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Orarend.Events
{
public class TimerEventArgs : EventArgs
{
/// <summary>
/// Lehet null
/// </summary>
public string KövetkezőÓra { get; }
/// <summary>
/// Lehet null
/// </summary>
public string HátralévőIdő { get; }
public TimerEventArgs(string kövóra, string hátralévőidő)
{
KövetkezőÓra = kövóra;
HátralévőIdő = hátralévőidő;
}
}
}

View file

@ -2,7 +2,7 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{93C1582B-AD0F-44EC-BB69-02EE1ADFC0DD}</ProjectGuid>
@ -13,8 +13,8 @@
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile44</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile111</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -33,28 +33,24 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<ItemGroup>
<Compile Include="API.cs" />
<Compile Include="Events\TimerEventArgs.cs" />
<Compile Include="Helyettesítés.cs" />
<Compile Include="Osztály.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Tanár.cs" />
<Compile Include="Timer.cs" />
<Compile Include="Óra.cs" />
<Compile Include="Órarend.cs" />
<Compile Include="ÓraTípus.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\portable-net45+netcore45+wp8+MonoAndroid+MonoTouch\HtmlAgilityPack.dll</HintPath>
<Reference Include="HtmlAgilityPack, Version=1.4.9.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.4\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid+MonoTouch\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll</HintPath>
<Reference Include="Mono.Android">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v6.0\Mono.Android.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -68,4 +64,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View file

@ -18,12 +18,34 @@ namespace Orarend
{
}
public override string ToString() => Név;
public override string ToString()
{
return Név;
}
public bool Equals(Osztály other) => Azonosító == other?.Azonosító;
public static bool operator==(Osztály a, Osztály b) => a?.Equals(b) ?? (object)b == null;
public static bool operator!=(Osztály a, Osztály b) => !(a == b);
public override bool Equals(object obj) => obj is Osztály ? Equals(obj as Osztály) : base.Equals(obj);
public override int GetHashCode() => Azonosító.GetHashCode();
public bool Equals(Osztály other)
{
return Azonosító == other?.Azonosító;
}
public static bool operator==(Osztály a, Osztály b)
{
return a?.Equals(b) ?? (object)b == null;
}
public static bool operator!=(Osztály a, Osztály b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
return obj is Osztály ? Equals(obj as Osztály) : base.Equals(obj);
}
public override int GetHashCode()
{
return Azonosító.GetHashCode();
}
}
}

View file

@ -2,7 +2,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
@ -16,7 +15,6 @@ using System.Security;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: SecurityTransparent]
// Version information for an assembly consists of the following four values:
//

View file

@ -7,9 +7,13 @@ using System.Threading.Tasks;
namespace Orarend
{
[DataContract] //
[DataContract]
public class Settings
{
[DataMember]
public bool DarkTheme { get; set; }
[DataMember]
public TimeSpan Difference { get; set; } //TODO
public void UseCommonNames()
{
set("mateme", "Matek");
@ -18,7 +22,6 @@ namespace Orarend
set(";prggy", "Programozás gyakorlat");
set("testns", "Tesi");
set("tapism", "Töri");
set("torten", "Töri");
set("matema", "Matek");
set("bioege", "Biosz");
set("foldra", "Föci");
@ -30,8 +33,5 @@ namespace Orarend
if (ÓraTípus.Típusok.ContainsKey(id))
ÓraTípus.Típusok[id].EgyediNév = name;
}
[DataMember]
public sbyte ÓraOffset { get; set; } = 0;
}
}

View file

@ -1,48 +0,0 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace SimpleTimerPortable
{
internal delegate void TimerCallback(object state);
internal sealed class Timer : CancellationTokenSource, IDisposable
{
public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)
{
this.callback = callback;
this.state = state;
start(dueTime, period);
}
private TimerCallback callback;
private object state;
private void start(TimeSpan dueTime, TimeSpan period)
{
Task.Delay(dueTime, Token).ContinueWith(async (t, s) =>
{
var tuple = (Tuple<TimerCallback, object>)s;
while (true)
{
if (IsCancellationRequested)
break;
await Task.Run(() => tuple.Item1(tuple.Item2));
await Task.Delay(period);
}
}, Tuple.Create(callback, state), CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default);
}
public new void Dispose() { base.Cancel(); }
public Timer Change(TimeSpan dueTime, TimeSpan period)
{
var timer = new Timer(callback, state, dueTime, period);
this.Dispose();
return timer;
}
}
}

View file

@ -1,8 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="portable45-net45+wp8" />
<package id="System.Collections" version="4.3.0" targetFramework="portable46-net451+win81" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="portable46-net451+win81" />
<package id="System.Runtime" version="4.3.0" targetFramework="portable46-net451+win81" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="portable46-net451+win81" />
</packages>
<package id="HtmlAgilityPack" version="1.4.9.4" targetFramework="portable45-net45+win8+wpa81" />
</packages>

View file

@ -10,6 +10,7 @@ namespace Orarend
[DataContract]
public class Óra
{
[DataMember]
private ÓraTípus Típus { get; set; }
[DataMember]
public Tanár Tanár { get; set; }
@ -20,11 +21,7 @@ namespace Orarend
/// </summary>
[DataMember]
public string[] Csoportok { get; set; }
[DataMember]
public bool ManuálisanHozzáadott { get; set; }
[DataMember]
public string Azonosító
{
get

View file

@ -7,29 +7,15 @@ namespace Orarend
public class ÓraTípus
{
[DataMember]
private string teljesnév;
public string TeljesNév
{
get
{
return teljesnév;
}
set
{
if ((value?.Trim()?.Length ?? 0) == 0)
teljesnév = "(" + Azonosító + ")";
else
teljesnév = value;
}
}
public string TeljesNév { get; set; }
[DataMember]
public string Azonosító { get; set; }
[DataMember]
public string EgyediNév { get; set; }
/// <summary>
/// A kulcs az óra azonosítója
/// </summary>
public static Dictionary<string, ÓraTípus> Típusok { get { return API.példány.típusok; } }
public static Dictionary<string, ÓraTípus> Típusok { get; } = new Dictionary<string, ÓraTípus>();
}
}

View file

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Security;
using System.Text;
using System.Threading.Tasks;

View file

@ -1,28 +0,0 @@
using Android.App;
using Android.OS;
using Android.Preferences;
using System.Security;
namespace OrarendAndroidApp
{
public class ActivityBase : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetTheme(this);
}
public static void SetTheme(Activity activity)
{
var settings = PreferenceManager.GetDefaultSharedPreferences(activity);
bool darktheme = settings.GetBoolean("pref_theme", false);
if (activity is ActivityBase ab)
ab.DarkTheme = darktheme;
activity.SetTheme(darktheme ? Android.Resource.Style.ThemeDeviceDefault : Android.Resource.Style.ThemeDeviceDefaultLight);
}
public bool DarkTheme;
}
}

View file

@ -11,13 +11,11 @@ using Android.Views;
using Android.Widget;
using Orarend;
using Android.Graphics;
using Android.Preferences;
using System.Security;
namespace OrarendAndroidApp
{
[Activity(Label = "AddActivity", Theme = "@android:style/Theme.Holo.Light")]
public class EditActivity : ActivityBase
public class EditActivity : Activity
{
private bool add;
private int index;
@ -46,9 +44,6 @@ namespace OrarendAndroidApp
osztálySpinner.SetSelection(ix);
FindViewById<EditText>(Resource.Id.csoportokEditText).Text = órarend.Csoportok.Aggregate((a, b) => a + " " + b);
}
else
FindViewById<EditText>(Resource.Id.névEditText).Text = "Órarend";
osztálySpinner.LayoutParameters = new TableRow.LayoutParams((osztálySpinner.Parent as View)?.Width - (osztálySpinner.Parent as ViewGroup)?.GetChildAt(0)?.Width ?? TableRow.LayoutParams.MatchParent, TableRow.LayoutParams.WrapContent); //TODO
FindViewById<Button>(Resource.Id.saveButton).Click += SaveButtonClick;
var deleteButton = FindViewById<Button>(Resource.Id.deleteButton);
if (add)
@ -71,7 +66,7 @@ namespace OrarendAndroidApp
intent.PutExtra("deleted", true);
((AlertDialog)s).Dismiss();
((AlertDialog)s).Dispose();
API.Mentés(OpenFileOutput(MainActivity.DATA_FILENAME, FileCreationMode.Private));
API.ÓrarendMentés(OpenFileOutput("orarend", FileCreationMode.Private));
SetResult(Result.Ok, intent);
Finish();
}).SetNegativeButton("Nem", (s, ea) =>
@ -95,7 +90,7 @@ namespace OrarendAndroidApp
}
else
API.Órarendek.Add(new Órarend(név, osztály, csoportok));
API.Mentés(OpenFileOutput(MainActivity.DATA_FILENAME, FileCreationMode.Private));
API.ÓrarendMentés(OpenFileOutput("orarend", FileCreationMode.Private));
SetResult(Result.Ok, Intent);
Finish();
}

View file

@ -13,53 +13,40 @@ using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Net;
using Android.Preferences;
using Orarend.Events;
using System.Security;
namespace OrarendAndroidApp
{
[Activity(Label = "Órarend", MainLauncher = true, Theme = "@android:style/Theme.DeviceDefault")]
public class MainActivity : ActivityBase
[Activity(Label = "Órarend", MainLauncher = true, Theme = "@android:style/Theme.Holo.Light")]
public class MainActivity : Activity
{
private Handler handler;
private Órarend órarend;
private Timer timer;
private const int EDIT_ADD_ACT_REQUEST = 1;
private const int SETTINGS_ACT_REQUEST = 2;
public const string DATA_FILENAME = "data.json";
protected override void OnCreate(Bundle bundle)
{
AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainLayout);
ActionBar.SetDisplayShowTitleEnabled(false);
ActionBar.CustomView = FindViewById<Spinner>(Resource.Id.spinner);
handler = new Handler();
string[] list = FileList();
if (list.Contains(DATA_FILENAME)
? API.Betöltés(OpenFileInput(DATA_FILENAME), e => Hiba("Hiba az adatok betöltése során!\n" + e)) : API.Betöltés())
{
API.CsengőTimerEvent += CsengőTimer;
API.Frissítéskor += (_, args) => HelyettesítésFrissítés(false, args);
}
if (list.Contains("beallitasok"))
API.BeállításBetöltés(OpenFileInput("beallitasok"), e => Hiba("Hiba a beállítások betöltése során!\n" + e));
if (list.Contains("orarend") && API.Órarendek.Count == 0)
API.ÓrarendBetöltés(OpenFileInput("orarend"), e => Hiba("Hiba az órarendek betöltése során!\n" + e));
if (list.Contains("osztaly") && API.Osztályok == null)
API.OsztályBetöltés(OpenFileInput("osztaly"), e => Hiba("Hiba az osztályok betöltése során!\n" + e));
timer = new Timer(CsengőTimer, null, new TimeSpan(0, 0, 1), new TimeSpan(0, 0, 1));
}
protected override void OnDestroy()
{
base.OnDestroy();
}
private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
if (!e.Handled) Hiba("Kezeletlen hiba!\n" + e.Exception);
e.Handled = true;
}
private Spinner list;
private void órarendlistafrissítés()
{
handler.Post(() =>
{
var list = FindViewById<Spinner>(Resource.Id.spinner);
int selected = list.SelectedItemPosition;
int count = list.Count;
ArrayAdapter adapter;
@ -84,70 +71,61 @@ namespace OrarendAndroidApp
private void ÓrarendClick(object sender, AdapterView.ItemSelectedEventArgs e)
{
API.ÓrarendKiválasztás(e.Position);
órarend = API.Órarendek[e.Position];
órarendfrissítés();
}
[SecuritySafeCritical]
private void addCell(string text, Color color, TableRow tr1, (int, int)? tag = null)
private void addCell(string text, Color color, TableRow tr1, int[] tag = null)
{
TextView textview = new TextView(this);
textview.SetText(text, TextView.BufferType.Normal);
textview.SetTextColor(color);
textview.SetPadding(10, 10, 10, 10);
textview.SetBackgroundResource(DarkTheme ? Resource.Drawable.cell_shape_dark : Resource.Drawable.cell_shape_light);
textview.Tag = tag.HasValue ? new JavaTuple<int, int>(tag.Value) : null;
textview.SetBackgroundResource(Resource.Drawable.cell_shape_light);
textview.Tag = tag;
textview.Clickable = true;
textview.Click += ÓraClick;
//textview.LongClick += ÓraLongClick;
RegisterForContextMenu(textview);
textview.ContextMenuCreated += ÓraContextMenuCreated;
tr1.AddView(textview);
}
[SecuritySafeCritical]
private class JavaTuple<T1, T2> : Java.Lang.Object
{
public (T1, T2) obj;
public JavaTuple((T1, T2) obj) => this.obj = obj;
public void Deconstruct(out T1 first, out T2 second) => (first, second) = obj;
}
private void HelyettesítésFrissítés(bool internethiba = true, API.FrissítésEventArgs args = null)
private void HelyettesítésFrissítés(bool internethiba = true)
{
var bar = FindViewById<ProgressBar>(Resource.Id.progressBar1);
//var menu = FindViewById<ActionMenuView>(Resource.Id.actionMenuView1);
Action loadstart = () => bar.Visibility = ViewStates.Visible;
if (internethiba)
handler.Post(loadstart);
else
handler.PostDelayed(loadstart, 500);
API.HelyettesítésFrissítés(() => OpenFileOutput(DATA_FILENAME, FileCreationMode.Private)).ContinueWith(t =>
var menu = FindViewById<ActionMenuView>(Resource.Id.actionMenuView1);
Action loadstart = () =>
{
bar.Visibility = ViewStates.Visible;
menu.Enabled = false;
};
handler.Post(loadstart);
API.HelyettesítésFrissítés(() => OpenFileOutput("orarend", FileCreationMode.Private)).ContinueWith(t =>
{
handler.RemoveCallbacks(loadstart);
handler.Post(() =>
{
bar.Visibility = ViewStates.Gone;
if (TaskHibaNemVolt(t, internethiba) && t.Result)
menu.Enabled = true;
if (TaskHiba(t, internethiba))
{
órarendfrissítés();
Toast.MakeText(this, "Helyettesítések frissítve", ToastLength.Short).Show();
if (args != null) args.Siker = true;
}
else if (!internethiba && args != null) args.Siker = true;
utolsófrissítésplusz1óra = DateTime.Now + new TimeSpan(1, 0, 0); //Mindenképpen állítsa be, hogy ne írja folyamatosan a hibát
});
});
}
private void ÓrarendFrissítés(bool auto, Órarend ór = null)
private void ÓrarendFrissítés(Órarend ór = null)
{
var bar = FindViewById<ProgressBar>(Resource.Id.progressBar1);
Action loadstart = () => bar.Visibility = ViewStates.Visible;
if (auto)
handler.PostDelayed(loadstart, 500);
else
handler.Post(loadstart);
API.Frissítés(() => OpenFileOutput(DATA_FILENAME, FileCreationMode.Private), ór).ContinueWith(t =>
var menu = FindViewById<ActionMenuView>(Resource.Id.actionMenuView1);
Action loadstart = () =>
{
bar.Visibility = ViewStates.Visible;
menu.Enabled = false;
};
handler.Post(loadstart);
API.Frissítés(() => OpenFileOutput("orarend", FileCreationMode.Private), () => OpenFileOutput("osztaly", FileCreationMode.Private), ór).ContinueWith(t =>
{
handler.RemoveCallbacks(loadstart);
handler.Post(() =>
@ -155,9 +133,9 @@ namespace OrarendAndroidApp
bar.Visibility = ViewStates.Gone;
órarendlistafrissítés();
HelyettesítésFrissítés();
if (TaskHibaNemVolt(t))
if (TaskHiba(t))
{
if (ór == null || ór == API.Órarend)
if (ór == null || ór == órarend)
órarendfrissítés();
Toast.MakeText(this, (API.Órarendek.Count > 0 ? "Órarend" + (ór == null ? "ek" : "") + " és o" : "O") + "sztálylista frissítve", ToastLength.Short).Show();
}
@ -167,28 +145,26 @@ namespace OrarendAndroidApp
private string[] Napok = new string[6] { "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat" };
[SecuritySafeCritical]
private void órarendfrissítés()
{
var table = FindViewById<TableLayout>(Resource.Id.tableLayout1);
deselect();
if (table.ChildCount > 0)
table.RemoveViews(0, table.ChildCount);
if (API.Órarend == null)
if (órarend == null)
return;
TableRow tr = new TableRow(this);
addCell(API.AHét ? "A" : "B", DarkTheme ? Color.White : Color.Black, tr);
addCell(API.AHét ? "A" : "B", Color.Black, tr);
for (int i = 0; i < Napok.Length; i++)
addCell(Napok[i], DarkTheme ? Color.White : Color.Black, tr);
addCell(Napok[i], Color.Black, tr);
table.AddView(tr, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
byte rowadds = 0;
for (int j = 0; j < 16; j++)
{
tr = new TableRow(this);
bool notnull = false;
for (int i = 0; i < 6; i++)
{ //Kihagyja az üres sorokat
if (API.Órarend.Órák[i][j] != null && API.HelyettesítésInnenIde(API.Órarend, i, j).Item2 != null)
if (órarend.Órák[i][j] != null)
{
notnull = true;
break;
@ -196,46 +172,21 @@ namespace OrarendAndroidApp
}
if (notnull)
{
for (int x = 0; x < rowadds; x++)
{
var tr1 = new TableRow(this);
addCell((j + x).ToString(), DarkTheme ? Color.White : Color.Black, tr1);
for (int i = 0; i < 6; i++)
addCell("", Color.Black, tr1);
table.AddView(tr1, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
}
rowadds = 0;
addCell((j + 1).ToString(), DarkTheme ? Color.White : Color.Black, tr);
addCell((j + 1).ToString(), Color.Black, tr);
for (int i = 0; i < 6; i++)
{
var (innen, ide) = API.HelyettesítésInnenIde(API.Órarend, i, j);
addCell(ide != null ? ide.ÚjÓra.EgyediNév : innen != null ? innen.EredetiNap != innen.ÚjNap || innen.EredetiSorszám != innen.ÚjSorszám ? "áthelyezve" : innen.ÚjÓra?.EgyediNév ?? "elmarad" : API.Órarend.Órák[i][j]?.EgyediNév ?? "", innen == null ? (DarkTheme ? Color.WhiteSmoke : Color.Black) : Color.Red, tr, (i, j));
var innenide = helyettesítésInnenIde(i, j);
var helyettesítés = innenide[0];
var helyettesítésIde = innenide[1];
//addCell(helyettesítés?.ÚjÓra?.EgyediNév ?? órarend.Órák[i][j]?.EgyediNév ?? "", helyettesítés == null ? Color.Black : Color.Red, tr, new int[2] { i, j });
addCell(helyettesítésIde != null ? helyettesítésIde.ÚjÓra.EgyediNév : helyettesítés != null ? helyettesítés.EredetiNap != helyettesítés.ÚjNap || helyettesítés.EredetiSorszám != helyettesítés.ÚjSorszám ? "Áthelyezve" : helyettesítés.ÚjÓra?.EgyediNév ?? "elmarad" : órarend.Órák[i][j]?.EgyediNév ?? "", helyettesítés == null ? Color.Black : Color.Red, tr, new int[2] { i, j });
}
table.AddView(tr, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent));
}
else rowadds++;
}
handler.Post(() => MaiNaphozGörgetés());
}
private (int i, int j, Óra óra, Helyettesítés innen, Helyettesítés ide)? TV2Óra(TextView tv)
{
var ij = (JavaTuple<int, int>)tv.Tag;
int i, j;
Helyettesítés innen, ide;
Óra óra;
if (ij != null)
{
(i, j) = ij;
(innen, ide) = API.HelyettesítésInnenIde(API.Órarend, i, j);
if ((óra = API.Órarend.Órák[i][j]) == null && ide?.ÚjÓra == null)
return null;
}
else
return null;
return (i, j, óra, innen, ide);
}
/// <summary>
/// A cellát nem frissíti, csak a szöveget tünteti el
/// </summary>
@ -246,38 +197,49 @@ namespace OrarendAndroidApp
selected = null;
}
private Helyettesítés[] helyettesítésInnenIde(int i, int j)
{
return new Helyettesítés[]
{
órarend.Helyettesítések.FirstOrDefault(h => (int)h.EredetiNap == i + 1 && h.EredetiSorszám == j + 1),
órarend.Helyettesítések.FirstOrDefault(h => (int)h.ÚjNap == i + 1 && h.ÚjSorszám == j + 1 && h.ÚjÓra != null) //Ha az eredeti óra elmarad, és ide lesz helyezve egy másik, az áthelyezést mutassa
};
}
private TextView selected;
/// <summary>
/// Kiválasztja az adott órát
/// </summary>
[SecuritySafeCritical]
private void ÓraClick(object sender, EventArgs e)
{
var tv = (TextView)sender;
var ij = (int[])tv.Tag;
if (selected != null && selected != sender)
selected.SetBackgroundResource(DarkTheme ? Resource.Drawable.cell_shape_dark : Resource.Drawable.cell_shape_light);
var x = TV2Óra(tv);
if (x == null)
selected.SetBackgroundResource(Resource.Drawable.cell_shape_light);
Óra óra;
Helyettesítés helyettesítésInnen = null;
Helyettesítés helyettesítésIde = null;
if (ij != null)
{
var innenide = helyettesítésInnenIde(ij[0], ij[1]);
helyettesítésInnen = innenide[0];
helyettesítésIde = innenide[1];
}
//if (ij == null || (óra = órarend.Órák[ij[0]][ij[1]] ?? ((helyettesítésIde = órarend.Helyettesítések.SingleOrDefault(h => (int)h.ÚjNap == ij[0] + 1 && h.ÚjSorszám == ij[1] + 1))?.ÚjÓra)) == null)
if (ij == null || (óra = órarend.Órák[ij[0]][ij[1]] ?? (helyettesítésIde?.ÚjÓra)) == null)
{ //Ha az óra nincs beállítva, beállítja a helyettesítettre - TODO: Ne; rejtse el
deselect();
return;
}
var (i, j, óra, helyettesítésInnen, helyettesítésIde) = x?.ToTuple();
tv.SetBackgroundResource(DarkTheme ? Resource.Drawable.cell_shape_selected_dark : Resource.Drawable.cell_shape_selected_light);
tv.SetBackgroundResource(Resource.Drawable.cell_shape_selected_light);
selected = tv;
var kivora = FindViewById<TextView>(Resource.Id.kivoraTV);
if (óra == null)
kivora.Visibility = ViewStates.Gone;
else
{
kivora.Text = Napok[i] + " " + (j + 1) + ". óra"
+ "\nNév: " + óra.TeljesNév
+ "\nTerem: " + óra.Terem
+ "\nTanár: " + óra.Tanár.Név
+ "\nIdőtartam: " + API.Órarend.Órakezdetek[j].ToString("hh\\:mm") + "-" + API.Órarend.Órakezdetek[j].Add(new TimeSpan(0, 45, 0)).ToString("hh\\:mm")
+ "\nCsoport: " + óra.Csoportok.Aggregate((a, b) => a + ", " + b);
kivora.Visibility = ViewStates.Visible;
}
kivora.Text = Napok[ij[0]] + " " + (ij[1] + 1) + ". óra"
+ "\nNév: " + óra.TeljesNév
+ "\nTerem: " + óra.Terem
+ "\nTanár: " + óra.Tanár.Név
+ "\nIdőtartam: " + órarend.Órakezdetek[ij[1]].ToString("hh\\:mm") + "-" + órarend.Órakezdetek[ij[1]].Add(new TimeSpan(0, 45, 0)).ToString("hh\\:mm")
+ "\nCsoport: " + óra.Csoportok.Aggregate((a, b) => a + ", " + b);
var hely = FindViewById<TextView>(Resource.Id.helyTV);
hely.Text = (helyettesítésInnen == null ? ""
: helyettesítésInnen.EredetiNap != helyettesítésInnen.ÚjNap || helyettesítésInnen.EredetiSorszám != helyettesítésInnen.ÚjSorszám
@ -288,67 +250,25 @@ namespace OrarendAndroidApp
+ (helyettesítésInnen.ÚjÓra.Terem != óra.Terem ? "\nTerem: " + helyettesítésInnen.ÚjÓra.Terem : "")
+ (helyettesítésInnen.ÚjÓra.Tanár.Név != óra.Tanár.Név ? "\nTanár: " + helyettesítésInnen.ÚjÓra.Tanár.Név : "")
+ (helyettesítésInnen.ÚjÓra.Csoportok[0] != óra.Csoportok[0] ? "\nCsoport: " + helyettesítésInnen.ÚjÓra.Csoportok.Aggregate((a, b) => a + ", " + b) : "")
: helyettesítésIde != null && (helyettesítésIde.EredetiNap != helyettesítésIde.ÚjNap || helyettesítésIde.EredetiSorszám != helyettesítésIde.ÚjSorszám)
? "" : "Az óra elmarad") //Ha át lett helyezve ide másik óra, akkor nem kell kiírni, hogy elmarad ez az óra
: "Az óra elmarad")
+ (helyettesítésIde == null ? ""
: helyettesítésIde.EredetiNap != helyettesítésIde.ÚjNap || helyettesítésIde.EredetiSorszám != helyettesítésIde.ÚjSorszám
? "Áthelyezve: " + Napok[(int)helyettesítésIde.EredetiNap - 1] + " " + helyettesítésIde.EredetiSorszám + ". óra --> ide"
+ (helyettesítésIde.ÚjÓra.EgyediNév != óra?.EgyediNév ? "\nÓra: " + helyettesítésIde.ÚjÓra.EgyediNév : "")
+ (helyettesítésIde.ÚjÓra.Terem != óra?.Terem ? "\nTerem: " + helyettesítésIde.ÚjÓra.Terem : "")
+ ((óra?.Tanár.Név != (helyettesítésIde.ÚjÓra.Tanár.Név == "" ? API.Órarend.Órák[(int)helyettesítésIde.EredetiNap - 1][helyettesítésIde.EredetiSorszám - 1].Tanár.Név : helyettesítésIde.ÚjÓra.Tanár.Név)) ? "\nTanár: " + (óra?.Tanár.Név == "" ? API.Órarend.Órák[(int)helyettesítésIde.EredetiNap - 1][helyettesítésIde.EredetiSorszám - 1].Tanár.Név : helyettesítésIde.ÚjÓra.Tanár.Név) : "")
+ (helyettesítésIde.ÚjÓra.Csoportok[0] != óra?.Csoportok[0] ? "\nCsoport: " + helyettesítésIde.ÚjÓra.Csoportok.Aggregate((a, b) => a + ", " + b) : "") //ˇˇ De ha változott, akkor nem
? "Áthelyezve: " + Napok[(int)helyettesítésInnen.EredetiNap - 1] + " " + helyettesítésIde.EredetiSorszám + ". óra --> ide"
+ (helyettesítésIde.ÚjÓra.EgyediNév != óra.EgyediNév ? "\nÓra: " + helyettesítésIde.ÚjÓra.EgyediNév : "")
+ (helyettesítésIde.ÚjÓra.Terem != óra.Terem ? "\nTerem: " + helyettesítésIde.ÚjÓra.Terem : "")
+ ((óra.Tanár.Név != (helyettesítésIde.ÚjÓra.Tanár.Név == "" ? órarend.Órák[(int)helyettesítésIde.EredetiNap - 1][helyettesítésIde.EredetiSorszám - 1].Tanár.Név : helyettesítésIde.ÚjÓra.Tanár.Név)) ? "\nTanár: " + (óra.Tanár.Név == "" ? órarend.Órák[(int)helyettesítésIde.EredetiNap - 1][helyettesítésIde.EredetiSorszám - 1].Tanár.Név : helyettesítésIde.ÚjÓra.Tanár.Név) : "")
+ (helyettesítésIde.ÚjÓra.Csoportok[0] != óra.Csoportok[0] ? "\nCsoport: " + helyettesítésIde.ÚjÓra.Csoportok.Aggregate((a, b) => a + ", " + b) : "") //ˇˇ De ha változott, akkor nem
: "") //Ha a pozicíó nem változott, a fentebbi rész már kiírta az adatait
;
hely.Visibility = hely.Text.Length > 0 ? ViewStates.Visible : ViewStates.Gone;
}
private void ÓraContextMenuCreated(object sender, View.CreateContextMenuEventArgs e)
{
switch (sender)
{
case TextView tv:
var x = TV2Óra(tv);
Óra óra;
if (x != null)
(_, _, óra, _, _) = x?.ToTuple();
else
óra = null;
if (óra == null)
{ //TODO
ÓraContextItemData.Add(e.Menu.Add("Hozzáadás"), () => StartActivity(new Intent(this, typeof(SettingsActivity))));
}
break;
default:
Hiba("Ismeretlen küldő a menühöz!");
break;
}
}
private Dictionary<IMenuItem, Action> ÓraContextItemData = new Dictionary<IMenuItem, Action>();
private T ctor<T>() where T : new() => new T();
public override bool OnContextItemSelected(IMenuItem item)
{
bool ret = ÓraContextItemData.ContainsKey(item);
if (ret)
ÓraContextItemData[item]();
return ret;
kivora.Visibility = ViewStates.Visible;
hely.Visibility = ViewStates.Visible;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.main_menu_light, menu);
ActionBar.SetCustomView(list = new Spinner(this, SpinnerMode.Dropdown), new ActionBar.LayoutParams(ActionBar.LayoutParams.MatchParent, ActionBar.LayoutParams.MatchParent, GravityFlags.Left));
ActionBar.SetDisplayShowCustomEnabled(true);
if (DarkTheme)
{
menu.FindItem(Resource.Id.menu_add).SetIcon(Resource.Drawable.ic_add_white_24dp);
menu.FindItem(Resource.Id.menu_edit).SetIcon(Resource.Drawable.ic_create_white_24dp);
menu.FindItem(Resource.Id.menu_refresh).SetIcon(Resource.Drawable.ic_autorenew_white_24dp);
menu.FindItem(Resource.Id.menu_preferences).SetIcon(Resource.Drawable.ic_settings_white_24dp);
}
if (API.Osztályok == null || API.Osztályok.Length == 0)
ÓrarendFrissítés(true);
ÓrarendFrissítés();
else
órarendlistafrissítés();
return base.OnCreateOptionsMenu(menu);
@ -372,36 +292,37 @@ namespace OrarendAndroidApp
}
case Resource.Id.menu_edit:
{
if (API.Órarend == null)
if (órarend == null)
{
Toast.MakeText(this, "Nincs órarend kiválasztva", ToastLength.Short).Show();
break;
}
var intent = new Intent(this, typeof(EditActivity));
intent.PutExtra("add", false);
intent.PutExtra("index", API.Órarendek.IndexOf(API.Órarend));
intent.PutExtra("index", API.Órarendek.IndexOf(órarend));
StartActivityForResult(intent, EDIT_ADD_ACT_REQUEST);
break;
}
case Resource.Id.menu_preferences:
{
var intent = new Intent(this, typeof(SettingsActivity));
StartActivityForResult(intent, SETTINGS_ACT_REQUEST);
break;
}
case Resource.Id.menu_preferences: //TODO
break;
case Resource.Id.menu_fullrefresh:
{
ÓrarendFrissítés(false);
ÓrarendFrissítés();
break;
}
}
return base.OnOptionsItemSelected(item);
}
private void Hiba(string msg) => Hiba(this, msg);
private void Hiba(string msg)
{
Hiba(this, msg);
}
public static void Hiba(Context c, string msg) =>
public static void Hiba(Context c, string msg)
{
new AlertDialog.Builder(c).SetMessage(msg).SetNeutralButton("OK", (s, e) => { ((AlertDialog)s).Dismiss(); ((AlertDialog)s).Dispose(); }).SetTitle("Hiba").Show();
}
/// <summary>
/// Az összes hibát kiírja, ami a <see cref="Task"/> futása közben keletkezett
@ -409,22 +330,15 @@ namespace OrarendAndroidApp
/// <param name="t"></param>
/// <param name="internethiba">Ha igaz, kiírja a WebException-öket is</param>
/// <returns>Igaz, ha nem volt hiba</returns>
private bool TaskHibaNemVolt(Task t, bool internethiba = true)
private bool TaskHiba(Task t, bool internethiba = true)
{
bool ret = true;
foreach (var ex in (IEnumerable<Exception>)t.Exception?.InnerExceptions ?? new Exception[0])
{
if (ex is WebException wex)
if (ex is WebException)
{
if (internethiba && wex.Status == WebExceptionStatus.ConnectFailure)
Hiba("Nem sikerült csatlakozni az E-naplóhoz.\nHa van internet, próbáld újraindítani az alkalmazást.");
else if (internethiba)
Hiba("Nem sikerült csatlakozni az E-naplóhoz.\n" + wex.Message);
}
else if (ex is InvalidOperationException oex && oex.Data.Contains("OERROR") && (string)oex.Data["OERROR"] == "CLS_NOT_FOUND")
{
ÓrarendFrissítés(true);
Toast.MakeText(this, oex.Message, ToastLength.Short).Show();
if (internethiba)
Hiba("Nem sikerült csatlakozni az E-naplóhoz.\n" + ex.Message);
}
else
Hiba(ex.ToString());
@ -433,60 +347,125 @@ namespace OrarendAndroidApp
return ret;
}
private void CsengőTimer(object sender, TimerEventArgs e)
private bool nincstöbbóra = false;
private void CsengőTimer(object state)
{
handler.Post(() =>
{
var kezdveg = FindViewById<TextView>(Resource.Id.kezdvegTV);
if (órarend == null)
{
kezdveg.Text = "Nincs órarend kiválasztva";
return;
}
var most = DateTime.Now - DateTime.Today;
//var most = new TimeSpan(8, 10, 0);
bool talált = false;
var kovora = FindViewById<TextView>(Resource.Id.kovoraTV);
kovora.Visibility = e.KövetkezőÓra == null ? ViewStates.Invisible : ViewStates.Visible;
kovora.Text = e.KövetkezőÓra ?? "";
kezdveg.Visibility = e.HátralévőIdő == null ? ViewStates.Invisible : ViewStates.Visible;
kezdveg.Text = e.HátralévőIdő ?? "";
nincstöbbóra = false;
if (órarend.Órakezdetek[0] == TimeSpan.Zero)
{ //Még nincsenek beállítva a kezdetek
kezdveg.Text = "Betöltés";
kovora.Visibility = ViewStates.Invisible;
return;
}
for (int i = 0; i < órarend.Órakezdetek.Length - 1; i++)
{
var vége = órarend.Órakezdetek[i].Add(new TimeSpan(0, 45, 0));
bool becsengetés;
if (most > órarend.Órakezdetek[i])
{
if (most < vége)
{
kezdveg.Text = "Kicsengetés: " + (vége - most).ToString("hh\\:mm\\:ss");
talált = true;
becsengetés = false;
}
else
continue;
}
else
{
kezdveg.Text = "Becsengetés: " + (órarend.Órakezdetek[i] - most).ToString("hh\\:mm\\:ss");
talált = true;
kovora.Visibility = ViewStates.Invisible;
becsengetés = true;
}
int x = (int)DateTime.Today.DayOfWeek - 1;
Óra óra;
var innenide = helyettesítésInnenIde(x, i);
if (x != -1 && x < 6 && (óra = innenide[1] != null ? innenide[1].ÚjÓra : innenide[0] != null ? innenide[0].EredetiNap != innenide[0].ÚjNap || innenide[0].EredetiSorszám != innenide[0].ÚjSorszám ? null : innenide[0].ÚjÓra : órarend.Órák[x][i]) != null)
{ //-1: Vasárnap
kovora.Text = (becsengetés ? "Következő" : "Jelenlegi") + " óra: " + óra.EgyediNév + "\n" + óra.Terem + "\n" + óra.Tanár.Név + "\n" + óra.Csoportok.Aggregate((a, b) => a + ", " + b);
kovora.Visibility = ViewStates.Visible;
kezdveg.Visibility = ViewStates.Visible;
break;
}
else
{
kovora.Visibility = ViewStates.Invisible;
kezdveg.Visibility = ViewStates.Invisible;
}
}
if (!talált)
{
kezdveg.Visibility = ViewStates.Invisible;
kovora.Visibility = ViewStates.Invisible;
nincstöbbóra = true;
}
});
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Canceled)
return;
int index = data.Extras.GetBoolean("add") ? API.Órarendek.Count - 1 : data.Extras.GetInt("index");
if (requestCode == EDIT_ADD_ACT_REQUEST)
{
if (resultCode == Result.Canceled)
return;
int index = data.Extras.GetBoolean("add") ? API.Órarendek.Count - 1 : data.Extras.GetInt("index");
if (!data.Extras.GetBoolean("deleted"))
ÓrarendFrissítés(false, API.Órarendek[index]);
ÓrarendFrissítés(API.Órarendek[index]);
else
{
API.ÓrarendKiválasztásTörlése();
órarend = null;
órarendfrissítés();
}
órarendlistafrissítés();
}
else if (requestCode == SETTINGS_ACT_REQUEST)
{
if (data?.Extras?.GetBoolean("offsetchanged") ?? false)
ÓrarendFrissítés(false);
Recreate();
}
}
public override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
API.Fókusz = hasFocus;
if (!hasFocus)
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
return;
}
timer.Change(new TimeSpan(0, 0, 0), new TimeSpan(0, 0, 1));
frissítésHa1ÓraEltelt();
MaiNaphozGörgetés();
}
private void MaiNaphozGörgetés()
{
var x = DateTime.Today.DayOfWeek;
if (nincstöbbóra) x++;
x = x == DayOfWeek.Sunday ? DayOfWeek.Monday : x;
var table = FindViewById<TableLayout>(Resource.Id.tableLayout1);
if (table.ChildCount == 0)
return;
var cell = (table.GetChildAt(0) as ViewGroup).GetChildAt((int)API.MaiNap);
var cell = (table.GetChildAt(0) as ViewGroup).GetChildAt((int)x);
FindViewById<HorizontalScrollView>(Resource.Id.horizontalView).SmoothScrollTo(Math.Max(cell.Left - (FindViewById(Resource.Id.container).Width - cell.Width) / 2, 0), 0);
}
private DateTime utolsófrissítésplusz1óra = DateTime.MinValue;
private void frissítésHa1ÓraEltelt()
{
if (utolsófrissítésplusz1óra > DateTime.Now)
return;
HelyettesítésFrissítés(false);
}
}
}

View file

@ -55,21 +55,15 @@
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ActivityBase.cs" />
<Compile Include="EditActivity.cs" />
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsActivity.cs" />
</ItemGroup>
<ItemGroup>
<None Include="GettingStarted.Xamarin" />
<None Include="packages.config" />
<None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" />
<AndroidResource Include="Resources\layout\MainLayout.axml">
@ -81,7 +75,6 @@
<AndroidResource Include="Resources\layout\EditLayout.axml">
<SubType>AndroidResource</SubType>
</AndroidResource>
<AndroidResource Include="Resources\menu\ora_menu.axml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\values\Strings.xml" />
@ -124,30 +117,15 @@
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\xml\preferences.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\cell_shape_dark.xml">
<AndroidResource Include="Resources\drawable\cell_shape_removed_light.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\cell_shape_selected_dark.xml">
<AndroidResource Include="Resources\drawable\cell_shape_added_light.xml">
<SubType>Designer</SubType>
</AndroidResource>
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_add_white_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_autorenew_white_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_create_white_24dp.png" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\drawable\ic_settings_white_24dp.png" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@ -156,4 +134,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.github.norbipeti.orarend" android:versionName="1.2" android:installLocation="auto" android:versionCode="2">
<uses-sdk android:minSdkVersion="11" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.github.norbipeti.orarend" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="Orarend"></application>
</manifest>

View file

@ -45,13 +45,13 @@ namespace OrarendAndroidApp
{
// aapt resource value: 0x7f020000
public const int cell_shape_dark = 2130837504;
public const int cell_shape_added_light = 2130837504;
// aapt resource value: 0x7f020001
public const int cell_shape_light = 2130837505;
// aapt resource value: 0x7f020002
public const int cell_shape_selected_dark = 2130837506;
public const int cell_shape_removed_light = 2130837506;
// aapt resource value: 0x7f020003
public const int cell_shape_selected_light = 2130837507;
@ -60,28 +60,16 @@ namespace OrarendAndroidApp
public const int ic_add_black_24dp = 2130837508;
// aapt resource value: 0x7f020005
public const int ic_add_white_24dp = 2130837509;
public const int ic_autorenew_black_24dp = 2130837509;
// aapt resource value: 0x7f020006
public const int ic_autorenew_black_24dp = 2130837510;
public const int ic_create_black_24dp = 2130837510;
// aapt resource value: 0x7f020007
public const int ic_autorenew_white_24dp = 2130837511;
public const int ic_settings_black_24dp = 2130837511;
// aapt resource value: 0x7f020008
public const int ic_create_black_24dp = 2130837512;
// aapt resource value: 0x7f020009
public const int ic_create_white_24dp = 2130837513;
// aapt resource value: 0x7f02000a
public const int ic_settings_black_24dp = 2130837514;
// aapt resource value: 0x7f02000b
public const int ic_settings_white_24dp = 2130837515;
// aapt resource value: 0x7f02000c
public const int Icon = 2130837516;
public const int Icon = 2130837512;
static Drawable()
{
@ -96,83 +84,89 @@ namespace OrarendAndroidApp
public partial class Id
{
// aapt resource value: 0x7f07000d
public const int ScrollView01 = 2131165197;
// aapt resource value: 0x7f06000d
public const int ScrollView01 = 2131099661;
// aapt resource value: 0x7f07000a
public const int ScrollView02 = 2131165194;
// aapt resource value: 0x7f06000a
public const int ScrollView02 = 2131099658;
// aapt resource value: 0x7f070009
public const int container = 2131165193;
// aapt resource value: 0x7f060015
public const int actionMenuView1 = 2131099669;
// aapt resource value: 0x7f070005
public const int csoportokEditText = 2131165189;
// aapt resource value: 0x7f060009
public const int container = 2131099657;
// aapt resource value: 0x7f070008
public const int deleteButton = 2131165192;
// aapt resource value: 0x7f060005
public const int csoportokEditText = 2131099653;
// aapt resource value: 0x7f070010
public const int helyTV = 2131165200;
// aapt resource value: 0x7f060008
public const int deleteButton = 2131099656;
// aapt resource value: 0x7f07000e
public const int horizontalView = 2131165198;
// aapt resource value: 0x7f060011
public const int helyTV = 2131099665;
// aapt resource value: 0x7f070012
public const int kezdvegTV = 2131165202;
// aapt resource value: 0x7f06000e
public const int horizontalView = 2131099662;
// aapt resource value: 0x7f070011
public const int kivoraTV = 2131165201;
// aapt resource value: 0x7f060012
public const int kezdvegTV = 2131099666;
// aapt resource value: 0x7f070013
public const int kovoraTV = 2131165203;
// aapt resource value: 0x7f060010
public const int kivoraTV = 2131099664;
// aapt resource value: 0x7f070016
public const int menu_add = 2131165206;
// aapt resource value: 0x7f060013
public const int kovoraTV = 2131099667;
// aapt resource value: 0x7f070017
public const int menu_edit = 2131165207;
// aapt resource value: 0x7f060018
public const int menu_add = 2131099672;
// aapt resource value: 0x7f070019
public const int menu_fullrefresh = 2131165209;
// aapt resource value: 0x7f060019
public const int menu_edit = 2131099673;
// aapt resource value: 0x7f070018
public const int menu_preferences = 2131165208;
// aapt resource value: 0x7f06001b
public const int menu_fullrefresh = 2131099675;
// aapt resource value: 0x7f070015
public const int menu_refresh = 2131165205;
// aapt resource value: 0x7f06001a
public const int menu_preferences = 2131099674;
// aapt resource value: 0x7f070001
public const int névEditText = 2131165185;
// aapt resource value: 0x7f060017
public const int menu_refresh = 2131099671;
// aapt resource value: 0x7f070014
public const int osztalylistaTV = 2131165204;
// aapt resource value: 0x7f060001
public const int névEditText = 2131099649;
// aapt resource value: 0x7f070003
public const int osztálySpinner = 2131165187;
// aapt resource value: 0x7f060014
public const int osztalylistaTV = 2131099668;
// aapt resource value: 0x7f07000c
public const int progressBar1 = 2131165196;
// aapt resource value: 0x7f060003
public const int osztálySpinner = 2131099651;
// aapt resource value: 0x7f070007
public const int saveButton = 2131165191;
// aapt resource value: 0x7f06000c
public const int progressBar1 = 2131099660;
// aapt resource value: 0x7f07000b
public const int scrollLinearLayout = 2131165195;
// aapt resource value: 0x7f060007
public const int saveButton = 2131099655;
// aapt resource value: 0x7f07000f
public const int tableLayout1 = 2131165199;
// aapt resource value: 0x7f06000b
public const int scrollLinearLayout = 2131099659;
// aapt resource value: 0x7f070000
public const int textView1 = 2131165184;
// aapt resource value: 0x7f060016
public const int spinner = 2131099670;
// aapt resource value: 0x7f070002
public const int textView2 = 2131165186;
// aapt resource value: 0x7f06000f
public const int tableLayout1 = 2131099663;
// aapt resource value: 0x7f070004
public const int textView3 = 2131165188;
// aapt resource value: 0x7f060000
public const int textView1 = 2131099648;
// aapt resource value: 0x7f070006
public const int textView4 = 2131165190;
// aapt resource value: 0x7f060002
public const int textView2 = 2131099650;
// aapt resource value: 0x7f060004
public const int textView3 = 2131099652;
// aapt resource value: 0x7f060006
public const int textView4 = 2131099654;
static Id()
{
@ -209,11 +203,8 @@ namespace OrarendAndroidApp
public partial class Menu
{
// aapt resource value: 0x7f060000
public const int main_menu_light = 2131099648;
// aapt resource value: 0x7f060001
public const int ora_menu = 2131099649;
// aapt resource value: 0x7f050000
public const int main_menu_light = 2131034112;
static Menu()
{
@ -228,11 +219,11 @@ namespace OrarendAndroidApp
public partial class String
{
// aapt resource value: 0x7f050001
public const int ApplicationName = 2131034113;
// aapt resource value: 0x7f040001
public const int ApplicationName = 2130968577;
// aapt resource value: 0x7f050000
public const int Hello = 2131034112;
// aapt resource value: 0x7f040000
public const int Hello = 2130968576;
static String()
{
@ -243,22 +234,6 @@ namespace OrarendAndroidApp
{
}
}
public partial class Xml
{
// aapt resource value: 0x7f040000
public const int preferences = 2130968576;
static Xml()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
}
private Xml()
{
}
}
}
}
#pragma warning restore 1591

View file

@ -2,6 +2,6 @@
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "rectangle" >
<solid android:color="#333"/>
<stroke android:width="1dp" android:color="#fff"/>
<solid android:color="#eee"/>
<stroke android:width="1dp" android:color="#00d"/>
</shape>

View file

@ -2,6 +2,6 @@
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape= "rectangle" >
<solid android:color="#222"/>
<stroke android:width="1dp" android:color="#fff"/>
<solid android:color="#eee"/>
<stroke android:width="1dp" android:color="#0d0"/>
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

View file

@ -31,7 +31,7 @@
<Spinner
android:layout_column="1"
android:id="@+id/osztálySpinner"
android:layout_width="500dp" />
android:layout_width="fill_parent" />
</TableRow>
<TableRow>
<TextView

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:orientation="vertical"
android:layout_width="fill_parent"
@ -55,6 +54,14 @@
android:isScrollContainer="true" />
</HorizontalScrollView>
</ScrollView>
<TextView
android:id="@+id/kivoraTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kiválasztott óra"
android:textSize="14sp"
android:textStyle="bold"
android:visibility="gone" />
<TextView
android:id="@+id/helyTV"
android:layout_width="wrap_content"
@ -64,14 +71,6 @@
android:textStyle="bold"
android:visibility="gone"
android:textColor="#FF0000" />
<TextView
android:id="@+id/kivoraTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Kiválasztott óra"
android:textSize="14sp"
android:textStyle="bold"
android:visibility="gone" />
<TextView
android:id="@+id/kezdvegTV"
android:text="Betöltés"
@ -97,4 +96,10 @@
android:visibility="gone" />
</LinearLayout>
</ScrollView>
<ActionMenuView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/actionMenuView1" />
</LinearLayout>

View file

@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- <item android:id="@+id/spinner"
<item android:id="@+id/spinner"
android:title="will be replaced anyway"
android:showAsAction="always"
android:actionViewClass="android.widget.Spinner"
android:layout_width="fill_parent" /> -->
android:actionViewClass="android.widget.Spinner" />
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_autorenew_black_24dp"
android:showAsAction="always"
android:showAsAction="always"
android:title="Frissítés" />
<item
android:id="@+id/menu_add"

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_refresh"
android:title="Frissítés" />
<item
android:id="@+id/menu_add"
android:title="Hozzáadás" />
<item
android:id="@+id/menu_edit"
android:title="Szerkesztés" />
<item
android:id="@+id/menu_preferences"
android:title="Beállítások" />
<item
android:id="@+id/menu_fullrefresh"
android:title="Órarendfrissítés" />
</menu>

View file

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="pref_theme"
android:title="Sötét téma"
android:summary="Sötét téma"
android:defaultValue="false" />
<Preference
android:key="pref_commonnames"
android:title="Gyakori óranevek"
android:summary="Gyakori óranevek használata" />
<EditTextPreference
android:key="pref_offset"
android:title="Óra eltolás"
android:summary="Pl. ha 1, akkor az első óra 8:15-kor kezdődik."
android:defaultValue="0"
android:numeric="integer" />
</PreferenceScreen>

View file

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Preferences;
using Orarend;
using System.Security;
namespace OrarendAndroidApp
{
[Activity(Label = "Beállítások", Theme = "@android:style/Theme.Holo.Light")]
public class SettingsActivity : PreferenceActivity, ISharedPreferencesOnSharedPreferenceChangeListener, Preference.IOnPreferenceClickListener
{
protected override void OnCreate(Bundle savedInstanceState)
{
ActivityBase.SetTheme(this);
/*var settings = PreferenceManager.GetDefaultSharedPreferences(this);
bool darktheme = settings.GetBoolean("pref_theme", false);
//SetTheme(darktheme ? Android.Resource.Style.ThemeDeviceDefault : Android.Resource.Style.ThemeDeviceDefaultLight);
SetTheme(darktheme ? Android.Resource.Style.ThemeHolo : Android.Resource.Style.ThemeHoloLight);*/
base.OnCreate(savedInstanceState);
#pragma warning disable CS0618 // Type or member is obsolete
AddPreferencesFromResource(Resource.Xml.preferences);
FindPreference("pref_commonnames").OnPreferenceClickListener = this;
#pragma warning restore CS0618 // Type or member is obsolete
PreferenceManager.SetDefaultValues(this, Resource.Xml.preferences, false);
}
private Intent intent;
public void OnSharedPreferenceChanged(ISharedPreferences sharedPreferences, string key)
{
switch (key)
{
case "pref_theme":
Recreate();
break;
case "pref_commonnames":
API.Beállítások.UseCommonNames();
Toast.MakeText(this, "Óranevek frissítve", ToastLength.Short).Show();
break;
case "pref_offset":
API.Beállítások.ÓraOffset = sbyte.Parse(sharedPreferences.GetString(key, "0"));
intent = new Intent(Intent);
intent.PutExtra("offsetchanged", true);
SetResult(Result.Ok, intent);
break;
}
}
protected override void OnResume()
{
base.OnResume();
PreferenceManager.GetDefaultSharedPreferences(this).RegisterOnSharedPreferenceChangeListener(this);
}
protected override void OnPause()
{
base.OnPause();
PreferenceManager.GetDefaultSharedPreferences(this).UnregisterOnSharedPreferenceChangeListener(this);
}
public override void OnBackPressed()
{
SetResult(Result.Ok, intent);
//base.OnBackPressed();
Finish();
}
public bool OnPreferenceClick(Preference preference)
{
if (preference.Key == "pref_commonnames")
{
API.Beállítások.UseCommonNames();
Toast.MakeText(this, "Óranevek frissítve", ToastLength.Short).Show();
}
return true;
}
}
}

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.ValueTuple" version="4.4.0" targetFramework="monoandroid60" />
</packages>

View file

@ -1,6 +0,0 @@
# Orarend
A school schedule app written in C# using Xamarin.
This app can obtain the schedule automatically from the school's website and update it as needed. Any temporary changes are marked red.
It downloads the site HTML and uses regex to fix some issues that the parser can't handle correctly and then parses the code.