From 217d095174c0cffc22301a7864234e2699d47adb Mon Sep 17 00:00:00 2001 From: Michael Gordeev Date: Thu, 23 Jan 2020 21:14:27 +0300 Subject: [PATCH] [1.0.7] Added schedule export for profs Now export preferences are kept --- .../GUT.Schedule/Activities/ExportActivity.cs | 25 +- .../GUT.Schedule/Activities/MainActivity.cs | 165 ++++++++++++- GUT.Schedule/GUT.Schedule/Calendar.cs | 50 +++- GUT.Schedule/GUT.Schedule/Extensions.cs | 22 ++ GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj | 1 + GUT.Schedule/GUT.Schedule/Models/DataSet.cs | 5 +- .../GUT.Schedule/Models/ProfessorSubject.cs | 44 ++++ GUT.Schedule/GUT.Schedule/Parser.cs | 36 ++- .../Properties/AndroidManifest.xml | 2 +- .../Resources/Resource.designer.cs | 226 +++++++++--------- .../Resources/layout/activity_main.xml | 79 ++++-- 11 files changed, 509 insertions(+), 146 deletions(-) create mode 100644 GUT.Schedule/GUT.Schedule/Models/ProfessorSubject.cs diff --git a/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs index bcf3385..dcef77c 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/ExportActivity.cs @@ -31,14 +31,29 @@ namespace GUT.Schedule { try { - status.Text = "Загрузка расписания"; - List schedule = await Parser.LoadSchedule(); + if(Data.DataSet.HttpClient != null) + { + status.Text = "Загрузка расписания с картофельных серверов Бонча"; + List schedule = new List(); - schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range + for (DateTime d = Data.StartDate; int.Parse($"{d.Year}{d.Month:00}") <= int.Parse($"{Data.EndDate.Year}{Data.EndDate.Month:00}"); d = d.AddMonths(1)) + schedule.AddRange(await Parser.GetProfessorSchedule(Data.DataSet.HttpClient, d)); - status.Text = "Экспортирование в календарь"; - Calendar.Export(schedule); + schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range + status.Text = "Экспортирование в календарь"; + Calendar.Export(schedule); + } + else + { + status.Text = "Загрузка расписания"; + List schedule = await Parser.LoadSchedule(); + + schedule = schedule.FindAll(i => i.StartTime.Date >= Data.StartDate && i.StartTime.Date <= Data.EndDate); // Filtering schedule according to export range + + status.Text = "Экспортирование в календарь"; + Calendar.Export(schedule); + } status.Text = "Готово"; await Task.Delay(1000); diff --git a/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs b/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs index 623986c..48be718 100644 --- a/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs +++ b/GUT.Schedule/GUT.Schedule/Activities/MainActivity.cs @@ -1,14 +1,18 @@ using System; using System.IO; using System.Linq; +using System.Net.Http; using Android.App; using Android.Content; using Android.OS; +using Android.Preferences; using Android.Support.V4.Text; using Android.Support.V7.App; using Android.Text.Method; using Android.Views; using Android.Widget; +using AngleSharp.Html.Dom; +using AngleSharp.Html.Parser; using GUT.Schedule.Models; namespace GUT.Schedule @@ -18,35 +22,64 @@ namespace GUT.Schedule { Button start, end, export; Button forDay, forWeek, forMonth, forSemester; - Spinner faculty, course, group, reminder, calendar; + Spinner faculty, course, group, reminder, calendar, user; CheckBox groupTitle; TextView error; + LinearLayout studentParams, profParams; + EditText email, password; + + ISharedPreferences prefs; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.activity_main); + prefs = PreferenceManager.GetDefaultSharedPreferences(this); + AssignVariables(); + + faculty.SetList(this, Data.Faculties.Select(i => i.Name)); + int s = Data.Faculties.FindIndex(i => i.Id == prefs.GetString("Faculty", "-123")); + faculty.SetSelection(s == -1 ? 0 : s); + + course.SetList(this, "1234".ToCharArray()); + course.SetSelection(prefs.GetInt("Course", 0)); // IDK why but this shit triggers events anyway (even if they are set in the next line. It seem to be that there's some asynchronous shit somewhere there) + // P.S. Fuck Android + AddEvents(); // Settings spinners' dropdown lists content - faculty.SetList(this, Data.Faculties.Select(i => i.Name)); - course.SetList(this, "1234".ToCharArray()); - reminder.SetList(this, new string[] + user.SetList(this, new[] + { + "Студент", + "Преподаватель" + }); + user.SetSelection(prefs.GetInt("User", 0)); + + reminder.SetList(this, new[] { "Нет", "Во время начала", "За 5 мин", "За 10 мин" }); + reminder.SetSelection(prefs.GetInt("Reminder", 0)); + calendar.SetList(this, Calendar.Calendars.Select(i => i.Name)); + s = Calendar.Calendars.FindIndex(i => i.Id == prefs.GetString("Calendar", "-123")); + calendar.SetSelection(s == -1 ? 0 : s); end.Text = Data.EndDate.ToShortDateString(); start.Text = Data.StartDate.ToShortDateString(); + + groupTitle.Checked = prefs.GetBoolean("AddGroupToHeader", false); + + email.Text = prefs.GetString("email", ""); + password.Text = prefs.GetString("password", ""); } - private void Export_Click(object sender, EventArgs e) + private async void Export_Click(object sender, EventArgs e) { error.Visibility = ViewStates.Gone; @@ -57,15 +90,82 @@ namespace GUT.Schedule return; } + HttpClient client = null; + if(user.SelectedItemPosition == 1) + { + Toast.MakeText(ApplicationContext, "Авторизация...", ToastLength.Short).Show(); + if (string.IsNullOrWhiteSpace(email.Text) || string.IsNullOrWhiteSpace(password.Text)) + { + error.Text = "Ошибка: Введите корректные учетные данные"; + error.Visibility = ViewStates.Visible; + return; + } + + export.Enabled = false; + client = new HttpClient(); + + await client.GetAsync("https://cabs.itut.ru/cabinet/"); + + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabs.itut.ru/cabinet/lib/autentificationok.php"); + request.SetContent( + ("users", email.Text), + ("parole", password.Text)); + + HttpResponseMessage response = await client.SendAsync(request); + string responseContent = await response.GetString(); + export.Enabled = true; + + if (!response.IsSuccessStatusCode) + { + error.Text = $"Ошибка авторизации: {response.StatusCode}: {responseContent}"; + error.Visibility = ViewStates.Visible; + return; + } + + if (!responseContent.StartsWith("1", StringComparison.OrdinalIgnoreCase)) + { + error.Text = $"Ошибка авторизации: Неверный e-mail и/или пароль ({string.Join("; ", responseContent.Replace("error=", "", StringComparison.OrdinalIgnoreCase).Split('|'))})"; + error.Visibility = ViewStates.Visible; + return; + } + + export.Enabled = false; + HttpResponseMessage verificationResponse = await client.GetAsync("https://cabs.itut.ru/cabinet/?login=yes"); + export.Enabled = true; + IHtmlDocument doc = new HtmlParser().ParseDocument(await verificationResponse.GetString()); + if (!doc.QuerySelectorAll("nobr").Any(i => i.TextContent.Contains("Ведомости"))) + { + error.Text = "Ошибка авторизации: Необходимо авторизоваться с аккаунтом преподавателя"; + error.Visibility = ViewStates.Visible; + return; + } + Data.Groups = null; + + // According to this SO thread: https://stackoverflow.com/questions/1925486/android-storing-username-and-password + // I consider Preferences as safe enough method for storing credentials + PreferenceManager.GetDefaultSharedPreferences(this).Edit().PutBoolean("email", groupTitle.Checked).Apply(); + PreferenceManager.GetDefaultSharedPreferences(this).Edit().PutBoolean("password", groupTitle.Checked).Apply(); + } + else + { + if(Data.Groups.Count < 1) + { + error.Text = "Ошибка: Не выбрана группа"; + error.Visibility = ViewStates.Visible; + return; + } + } + // Forming export parameters Data.DataSet = new DataSet { Faculty = Data.Faculties[faculty.SelectedItemPosition].Id, - Group = Data.Groups[group.SelectedItemPosition].Id, + Group = Data.Groups?[group.SelectedItemPosition].Id, Course = course.SelectedItemPosition + 1, AddGroupToTitle = groupTitle.Checked, Calendar = Calendar.Calendars[calendar.SelectedItemPosition].Id, - Reminder = (reminder.SelectedItemPosition - 1) * 5 + Reminder = (reminder.SelectedItemPosition - 1) * 5, + HttpClient = client }; StartActivity(new Intent(this, typeof(ExportActivity))); @@ -83,13 +183,16 @@ namespace GUT.Schedule start.Text = Data.StartDate.ToShortDateString(); } - private async void UpdateGroupsList(object sender, AdapterView.ItemSelectedEventArgs e) + private async void UpdateGroupsList() { if (course.SelectedItem == null) return; await Parser.LoadGroups(Data.Faculties[faculty.SelectedItemPosition].Id, course.SelectedItemPosition + 1); group.SetList(this, Data.Groups.Select(i => i.Name)); + + int s = Data.Groups?.FindIndex(i => i.Id == prefs.GetString("Group", "-123")) ?? 0; + group.SetSelection(s == -1 ? 0 : s); } private void SetDate(int days) @@ -115,15 +218,57 @@ namespace GUT.Schedule group = FindViewById(Resource.Id.group); reminder = FindViewById(Resource.Id.reminder); calendar = FindViewById(Resource.Id.calendar); + user = FindViewById(Resource.Id.user); error = FindViewById(Resource.Id.error); groupTitle = FindViewById(Resource.Id.groupTitle); + + studentParams = FindViewById(Resource.Id.studentParams); + profParams = FindViewById(Resource.Id.professorParams); + + email = FindViewById(Resource.Id.email); + password = FindViewById(Resource.Id.password); } private void AddEvents() { - faculty.ItemSelected += UpdateGroupsList; - course.ItemSelected += UpdateGroupsList; + faculty.ItemSelected += (s, e) => + { + prefs.Edit().PutString("Faculty", Data.Faculties[e.Position].Id).Apply(); + UpdateGroupsList(); + }; + course.ItemSelected += (s, e) => + { + prefs.Edit().PutInt("Course", e.Position).Apply(); + UpdateGroupsList(); + }; + user.ItemSelected += (s, e) => + { + prefs.Edit().PutInt("User", e.Position).Apply(); + switch (e.Position) + { + case 0: + studentParams.Visibility = ViewStates.Visible; + groupTitle.Visibility = ViewStates.Visible; + profParams.Visibility = ViewStates.Gone; + break; + case 1: + studentParams.Visibility = ViewStates.Gone; + groupTitle.Visibility = ViewStates.Gone; + profParams.Visibility = ViewStates.Visible; + break; + } + }; + calendar.ItemSelected += (s, e) => + prefs.Edit().PutString("Calendar", Calendar.Calendars[e.Position].Id).Apply(); + reminder.ItemSelected += (s, e) => + prefs.Edit().PutInt("Reminder", e.Position).Apply(); + group.ItemSelected += (s, e) => + prefs.Edit().PutString("Group", Data.Groups[e.Position].Id).Apply(); + + groupTitle.Click += (s, e) => + prefs.Edit().PutBoolean("AddGroupToHeader", groupTitle.Checked).Apply(); + forDay.Click += (s, e) => SetDate(0); forWeek.Click += (s, e) => SetDate(6); diff --git a/GUT.Schedule/GUT.Schedule/Calendar.cs b/GUT.Schedule/GUT.Schedule/Calendar.cs index 937a8ab..2c216e5 100644 --- a/GUT.Schedule/GUT.Schedule/Calendar.cs +++ b/GUT.Schedule/GUT.Schedule/Calendar.cs @@ -46,7 +46,7 @@ namespace GUT.Schedule foreach (Subject item in schedule) { - Android.Content.ContentValues eventValues = new Android.Content.ContentValues(); + ContentValues eventValues = new ContentValues(); eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, data.Calendar); @@ -65,7 +65,7 @@ namespace GUT.Schedule // For some reason Google calendars ignore HasAlarm = false and set reminder for 30 minutes. Local calendars don't seem to have this issue eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, item.StartTime.ToUnixTime()); - eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, Extensions.ToUnixTime(item.EndTime)); + eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, item.EndTime.ToUnixTime()); eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID); eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID); @@ -76,7 +76,51 @@ namespace GUT.Schedule // Settings reminder if(data.Reminder != -5) { - Android.Content.ContentValues reminderValues = new Android.Content.ContentValues(); + ContentValues reminderValues = new ContentValues(); + reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment)); + reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, data.Reminder); + + Application.Context.ContentResolver.Insert(CalendarContract.Reminders.ContentUri, reminderValues); + } + } + } + + public static void Export(IEnumerable schedule) + { + DataSet data = Data.DataSet; + + foreach (ProfessorSubject item in schedule) + { + ContentValues eventValues = new ContentValues(); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.CalendarId, data.Calendar); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.Title, string.Format("{0}. {1} ({2})", + item.Order, + item.Name, + item.Type)); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.Description, item.Groups); + eventValues.Put(CalendarContract.Events.InterfaceConsts.EventLocation, item.Cabinet); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.Availability, 0); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.HasAlarm, data.Reminder != -5); + // For some reason Google calendars ignore HasAlarm = false and set reminder for 30 minutes. Local calendars don't seem to have this issue + + eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtstart, item.StartTime.ToUnixTime()); + eventValues.Put(CalendarContract.Events.InterfaceConsts.Dtend, item.EndTime.ToUnixTime()); + + eventValues.Put(CalendarContract.Events.InterfaceConsts.EventTimezone, TimeZone.Default.ID); + eventValues.Put(CalendarContract.Events.InterfaceConsts.EventEndTimezone, TimeZone.Default.ID); + eventValues.Put(CalendarContract.Events.InterfaceConsts.CustomAppPackage, Application.Context.PackageName); + + Uri response = Application.Context.ContentResolver.Insert(CalendarContract.Events.ContentUri, eventValues); + + // Settings reminder + if(data.Reminder != -5) + { + ContentValues reminderValues = new ContentValues(); reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.EventId, long.Parse(response.LastPathSegment)); reminderValues.Put(CalendarContract.Reminders.InterfaceConsts.Minutes, data.Reminder); diff --git a/GUT.Schedule/GUT.Schedule/Extensions.cs b/GUT.Schedule/GUT.Schedule/Extensions.cs index 5643345..7ce8c71 100644 --- a/GUT.Schedule/GUT.Schedule/Extensions.cs +++ b/GUT.Schedule/GUT.Schedule/Extensions.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; using Android.Content; using Android.Widget; @@ -45,5 +48,24 @@ namespace GUT.Schedule /// which is represented by total milliseconds count passed since 1970 public static long ToUnixTime(this DateTime dt) => (long)dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; + + public static void SetContent(this HttpRequestMessage request, params (string key, string value)[] values) + { + if (request == null) + throw new ArgumentNullException(nameof(request)); + + Dictionary body = new Dictionary(); + foreach ((string key, string value) in values) + body.Add(key, value); + request.Content = new FormUrlEncodedContent(body); + } + public static async Task GetString(this HttpResponseMessage response) + { + if (response == null) + throw new ArgumentNullException(nameof(response)); + + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + return Encoding.GetEncoding("Windows-1251").GetString(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false)); + } } } \ No newline at end of file diff --git a/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj b/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj index 916813e..45929f2 100644 --- a/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj +++ b/GUT.Schedule/GUT.Schedule/GUT.Schedule.csproj @@ -75,6 +75,7 @@ + diff --git a/GUT.Schedule/GUT.Schedule/Models/DataSet.cs b/GUT.Schedule/GUT.Schedule/Models/DataSet.cs index c093f5f..4c5e288 100644 --- a/GUT.Schedule/GUT.Schedule/Models/DataSet.cs +++ b/GUT.Schedule/GUT.Schedule/Models/DataSet.cs @@ -1,4 +1,6 @@ -namespace GUT.Schedule.Models +using System.Net.Http; + +namespace GUT.Schedule.Models { public class DataSet { @@ -8,5 +10,6 @@ public string Group { get; set; } public int Reminder { get; set; } public bool AddGroupToTitle { get; set; } + public HttpClient HttpClient { get; set; } } } \ No newline at end of file diff --git a/GUT.Schedule/GUT.Schedule/Models/ProfessorSubject.cs b/GUT.Schedule/GUT.Schedule/Models/ProfessorSubject.cs new file mode 100644 index 0000000..dac01b8 --- /dev/null +++ b/GUT.Schedule/GUT.Schedule/Models/ProfessorSubject.cs @@ -0,0 +1,44 @@ +using System; + +namespace GUT.Schedule.Models +{ + public class ProfessorSubject + { + public string Name { get; set; } + public string Type { get; set; } + public string Cabinet { get; set; } + public string Order { get; set; } + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + public string Groups { get; set; } + + public ProfessorSubject(string name, string type, string cabinet, string groups, int year, int month, int day, string schedule) + { + Name = name; + Type = type; + Cabinet = cabinet; + Groups = groups; + + string[] time = schedule.Split('-'); + + StartTime = new DateTime(year, month, day, int.Parse(time[0].Split('.')[0]), int.Parse(time[0].Split('.')[1]), 0); + EndTime = new DateTime(year, month, day, int.Parse(time[1].Split('.')[0]), int.Parse(time[1].Split('.')[1]), 0); + Order = time[0] switch + { + "09.00" => "1", + "10.45" => "2", + "13.00" => "3", + "14.45" => "4", + "16.30" => "5", + "18.15" => "6", + "20.00" => "7", + "10.30" => "2", //Расписание для пар по физ-ре + "12.00" => "3", + "13.30" => "4", + "15.00" => "5", + "18.00" => "7", + _ => "" + }; + } + } +} \ No newline at end of file diff --git a/GUT.Schedule/GUT.Schedule/Parser.cs b/GUT.Schedule/GUT.Schedule/Parser.cs index afcedff..b72f25c 100644 --- a/GUT.Schedule/GUT.Schedule/Parser.cs +++ b/GUT.Schedule/GUT.Schedule/Parser.cs @@ -89,7 +89,6 @@ namespace GUT.Schedule public static async Task LoadGroups(string facultyId, int course) { - Data.Groups = new List<(string, string)>(); using HttpClient client = new HttpClient(); Dictionary requestBody = new Dictionary { @@ -107,6 +106,7 @@ namespace GUT.Schedule HttpResponseMessage response = await client.SendAsync(request); string responseBody = await response.Content.ReadAsStringAsync(); + Data.Groups = new List<(string, string)>(); foreach (string s in responseBody.Split(';')) try { Data.Groups.Add((s.Split(',')[0], s.Split(',')[1])); } catch { } @@ -122,5 +122,39 @@ namespace GUT.Schedule return $"205.{now.Year - 2001}{now.Year - 2000}/2"; } + public static async Task> GetProfessorSchedule(HttpClient client, DateTime date) + { + using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://cabs.itut.ru/cabinet/project/cabinet/forms/pr_raspisanie_kalendar.php"); + request.SetContent( + ("month", date.Month.ToString()), + ("year", date.Year.ToString()), + ("type_z", "0")); + + HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false); + string responseContent = await response.GetString().ConfigureAwait(false); + + if (!response.IsSuccessStatusCode) + throw new HttpRequestException(responseContent); + + IHtmlDocument doc = new HtmlParser().ParseDocument(responseContent); + List schedule = new List(); + foreach(var i in doc.QuerySelectorAll("td").Where(i => i.GetAttribute("style") == "text-align: center; vertical-align: top")) + for (int k = 0; k < i.QuerySelectorAll("i").Length; k++) + { + ProfessorSubject item = new ProfessorSubject( + name: i.QuerySelectorAll("b")[k * 2 + 1].TextContent, + type: i.QuerySelectorAll("i")[k].TextContent, + cabinet: i.ChildNodes[k * 13 + 12].TextContent, + groups: i.ChildNodes[k * 13 + 7].TextContent, + year: date.Year, + month: date.Month, + day: int.Parse(i.QuerySelectorAll("b")[0].TextContent), + schedule: i.QuerySelectorAll("b")[k * 2 + 2].TextContent + ); + schedule.Add(item); + } + + return schedule; + } } } \ No newline at end of file diff --git a/GUT.Schedule/GUT.Schedule/Properties/AndroidManifest.xml b/GUT.Schedule/GUT.Schedule/Properties/AndroidManifest.xml index 091eb0a..3638e05 100644 --- a/GUT.Schedule/GUT.Schedule/Properties/AndroidManifest.xml +++ b/GUT.Schedule/GUT.Schedule/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@  - + diff --git a/GUT.Schedule/GUT.Schedule/Resources/Resource.designer.cs b/GUT.Schedule/GUT.Schedule/Resources/Resource.designer.cs index 456984f..a2bcdfa 100644 --- a/GUT.Schedule/GUT.Schedule/Resources/Resource.designer.cs +++ b/GUT.Schedule/GUT.Schedule/Resources/Resource.designer.cs @@ -3590,253 +3590,265 @@ namespace GUT.Schedule public const int parent_matrix = 2131230844; // aapt resource value: 0x7F08007D - public const int pin = 2131230845; + public const int password = 2131230845; // aapt resource value: 0x7F08007E - public const int progress_circular = 2131230846; + public const int pin = 2131230846; // aapt resource value: 0x7F08007F - public const int progress_horizontal = 2131230847; + public const int professorParams = 2131230847; // aapt resource value: 0x7F080080 - public const int radio = 2131230848; + public const int progress_circular = 2131230848; // aapt resource value: 0x7F080081 - public const int reminder = 2131230849; + public const int progress_horizontal = 2131230849; // aapt resource value: 0x7F080082 - public const int right = 2131230850; + public const int radio = 2131230850; // aapt resource value: 0x7F080083 - public const int right_icon = 2131230851; + public const int reminder = 2131230851; // aapt resource value: 0x7F080084 - public const int right_side = 2131230852; + public const int right = 2131230852; // aapt resource value: 0x7F080085 - public const int save_image_matrix = 2131230853; + public const int right_icon = 2131230853; // aapt resource value: 0x7F080086 - public const int save_non_transition_alpha = 2131230854; + public const int right_side = 2131230854; // aapt resource value: 0x7F080087 - public const int save_scale_type = 2131230855; + public const int save_image_matrix = 2131230855; // aapt resource value: 0x7F080088 - public const int screen = 2131230856; + public const int save_non_transition_alpha = 2131230856; // aapt resource value: 0x7F080089 - public const int scroll = 2131230857; - - // aapt resource value: 0x7F08008D - public const int scrollable = 2131230861; + public const int save_scale_type = 2131230857; // aapt resource value: 0x7F08008A - public const int scrollIndicatorDown = 2131230858; + public const int screen = 2131230858; // aapt resource value: 0x7F08008B - public const int scrollIndicatorUp = 2131230859; - - // aapt resource value: 0x7F08008C - public const int scrollView = 2131230860; - - // aapt resource value: 0x7F08008E - public const int search_badge = 2131230862; + public const int scroll = 2131230859; // aapt resource value: 0x7F08008F - public const int search_bar = 2131230863; + public const int scrollable = 2131230863; + + // aapt resource value: 0x7F08008C + public const int scrollIndicatorDown = 2131230860; + + // aapt resource value: 0x7F08008D + public const int scrollIndicatorUp = 2131230861; + + // aapt resource value: 0x7F08008E + public const int scrollView = 2131230862; // aapt resource value: 0x7F080090 - public const int search_button = 2131230864; + public const int search_badge = 2131230864; // aapt resource value: 0x7F080091 - public const int search_close_btn = 2131230865; + public const int search_bar = 2131230865; // aapt resource value: 0x7F080092 - public const int search_edit_frame = 2131230866; + public const int search_button = 2131230866; // aapt resource value: 0x7F080093 - public const int search_go_btn = 2131230867; + public const int search_close_btn = 2131230867; // aapt resource value: 0x7F080094 - public const int search_mag_icon = 2131230868; + public const int search_edit_frame = 2131230868; // aapt resource value: 0x7F080095 - public const int search_plate = 2131230869; + public const int search_go_btn = 2131230869; // aapt resource value: 0x7F080096 - public const int search_src_text = 2131230870; + public const int search_mag_icon = 2131230870; // aapt resource value: 0x7F080097 - public const int search_voice_btn = 2131230871; - - // aapt resource value: 0x7F080099 - public const int selected = 2131230873; + public const int search_plate = 2131230871; // aapt resource value: 0x7F080098 - public const int select_dialog_listview = 2131230872; + public const int search_src_text = 2131230872; + + // aapt resource value: 0x7F080099 + public const int search_voice_btn = 2131230873; + + // aapt resource value: 0x7F08009B + public const int selected = 2131230875; + + // aapt resource value: 0x7F08009A + public const int select_dialog_listview = 2131230874; // aapt resource value: 0x7F080004 public const int SHIFT = 2131230724; - // aapt resource value: 0x7F08009A - public const int shortcut = 2131230874; - - // aapt resource value: 0x7F08009B - public const int showCustom = 2131230875; - // aapt resource value: 0x7F08009C - public const int showHome = 2131230876; + public const int shortcut = 2131230876; // aapt resource value: 0x7F08009D - public const int showTitle = 2131230877; + public const int showCustom = 2131230877; // aapt resource value: 0x7F08009E - public const int smallLabel = 2131230878; + public const int showHome = 2131230878; // aapt resource value: 0x7F08009F - public const int snackbar_action = 2131230879; + public const int showTitle = 2131230879; // aapt resource value: 0x7F0800A0 - public const int snackbar_text = 2131230880; + public const int smallLabel = 2131230880; // aapt resource value: 0x7F0800A1 - public const int snap = 2131230881; + public const int snackbar_action = 2131230881; // aapt resource value: 0x7F0800A2 - public const int snapMargins = 2131230882; + public const int snackbar_text = 2131230882; // aapt resource value: 0x7F0800A3 - public const int spacer = 2131230883; + public const int snap = 2131230883; // aapt resource value: 0x7F0800A4 - public const int split_action_bar = 2131230884; + public const int snapMargins = 2131230884; // aapt resource value: 0x7F0800A5 - public const int src_atop = 2131230885; + public const int spacer = 2131230885; // aapt resource value: 0x7F0800A6 - public const int src_in = 2131230886; + public const int split_action_bar = 2131230886; // aapt resource value: 0x7F0800A7 - public const int src_over = 2131230887; + public const int src_atop = 2131230887; // aapt resource value: 0x7F0800A8 - public const int start = 2131230888; + public const int src_in = 2131230888; // aapt resource value: 0x7F0800A9 - public const int status = 2131230889; + public const int src_over = 2131230889; // aapt resource value: 0x7F0800AA - public const int stretch = 2131230890; + public const int start = 2131230890; // aapt resource value: 0x7F0800AB - public const int submenuarrow = 2131230891; + public const int status = 2131230891; // aapt resource value: 0x7F0800AC - public const int submit_area = 2131230892; + public const int stretch = 2131230892; + + // aapt resource value: 0x7F0800AD + public const int studentParams = 2131230893; + + // aapt resource value: 0x7F0800AE + public const int submenuarrow = 2131230894; + + // aapt resource value: 0x7F0800AF + public const int submit_area = 2131230895; // aapt resource value: 0x7F080005 public const int SYM = 2131230725; - // aapt resource value: 0x7F0800AD - public const int tabMode = 2131230893; - - // aapt resource value: 0x7F0800AE - public const int tag_transition_group = 2131230894; - - // aapt resource value: 0x7F0800AF - public const int tag_unhandled_key_event_manager = 2131230895; - // aapt resource value: 0x7F0800B0 - public const int tag_unhandled_key_listeners = 2131230896; + public const int tabMode = 2131230896; // aapt resource value: 0x7F0800B1 - public const int text = 2131230897; + public const int tag_transition_group = 2131230897; // aapt resource value: 0x7F0800B2 - public const int text2 = 2131230898; - - // aapt resource value: 0x7F0800B7 - public const int textinput_counter = 2131230903; - - // aapt resource value: 0x7F0800B8 - public const int textinput_error = 2131230904; - - // aapt resource value: 0x7F0800B9 - public const int textinput_helper_text = 2131230905; + public const int tag_unhandled_key_event_manager = 2131230898; // aapt resource value: 0x7F0800B3 - public const int textSpacerNoButtons = 2131230899; + public const int tag_unhandled_key_listeners = 2131230899; // aapt resource value: 0x7F0800B4 - public const int textSpacerNoTitle = 2131230900; + public const int text = 2131230900; // aapt resource value: 0x7F0800B5 - public const int textStart = 2131230901; - - // aapt resource value: 0x7F0800B6 - public const int text_input_password_toggle = 2131230902; + public const int text2 = 2131230901; // aapt resource value: 0x7F0800BA - public const int time = 2131230906; + public const int textinput_counter = 2131230906; // aapt resource value: 0x7F0800BB - public const int title = 2131230907; + public const int textinput_error = 2131230907; // aapt resource value: 0x7F0800BC - public const int titleDividerNoCustom = 2131230908; + public const int textinput_helper_text = 2131230908; + + // aapt resource value: 0x7F0800B6 + public const int textSpacerNoButtons = 2131230902; + + // aapt resource value: 0x7F0800B7 + public const int textSpacerNoTitle = 2131230903; + + // aapt resource value: 0x7F0800B8 + public const int textStart = 2131230904; + + // aapt resource value: 0x7F0800B9 + public const int text_input_password_toggle = 2131230905; // aapt resource value: 0x7F0800BD - public const int title_template = 2131230909; + public const int time = 2131230909; // aapt resource value: 0x7F0800BE - public const int top = 2131230910; + public const int title = 2131230910; // aapt resource value: 0x7F0800BF - public const int topPanel = 2131230911; + public const int titleDividerNoCustom = 2131230911; // aapt resource value: 0x7F0800C0 - public const int touch_outside = 2131230912; + public const int title_template = 2131230912; // aapt resource value: 0x7F0800C1 - public const int transition_current_scene = 2131230913; + public const int top = 2131230913; // aapt resource value: 0x7F0800C2 - public const int transition_layout_save = 2131230914; + public const int topPanel = 2131230914; // aapt resource value: 0x7F0800C3 - public const int transition_position = 2131230915; + public const int touch_outside = 2131230915; // aapt resource value: 0x7F0800C4 - public const int transition_scene_layoutid_cache = 2131230916; + public const int transition_current_scene = 2131230916; // aapt resource value: 0x7F0800C5 - public const int transition_transform = 2131230917; + public const int transition_layout_save = 2131230917; // aapt resource value: 0x7F0800C6 - public const int uniform = 2131230918; + public const int transition_position = 2131230918; // aapt resource value: 0x7F0800C7 - public const int unlabeled = 2131230919; + public const int transition_scene_layoutid_cache = 2131230919; // aapt resource value: 0x7F0800C8 - public const int up = 2131230920; + public const int transition_transform = 2131230920; // aapt resource value: 0x7F0800C9 - public const int useLogo = 2131230921; + public const int uniform = 2131230921; // aapt resource value: 0x7F0800CA - public const int view_offset_helper = 2131230922; + public const int unlabeled = 2131230922; // aapt resource value: 0x7F0800CB - public const int visible = 2131230923; + public const int up = 2131230923; // aapt resource value: 0x7F0800CC - public const int withText = 2131230924; + public const int useLogo = 2131230924; // aapt resource value: 0x7F0800CD - public const int wrap_content = 2131230925; + public const int user = 2131230925; + + // aapt resource value: 0x7F0800CE + public const int view_offset_helper = 2131230926; + + // aapt resource value: 0x7F0800CF + public const int visible = 2131230927; + + // aapt resource value: 0x7F0800D0 + public const int withText = 2131230928; + + // aapt resource value: 0x7F0800D1 + public const int wrap_content = 2131230929; static Id() { diff --git a/GUT.Schedule/GUT.Schedule/Resources/layout/activity_main.xml b/GUT.Schedule/GUT.Schedule/Resources/layout/activity_main.xml index b6a1d37..0c8b701 100644 --- a/GUT.Schedule/GUT.Schedule/Resources/layout/activity_main.xml +++ b/GUT.Schedule/GUT.Schedule/Resources/layout/activity_main.xml @@ -19,35 +19,78 @@ android:textStyle="bold" android:textSize="16dp"/> - - - + android:orientation="vertical" + android:visibility="gone"> - + - + + + + + + + + + + + + android:orientation="vertical" + android:visibility="gone"> - + + + + + + + +