tmis 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +674 -0
  3. data/README.md +44 -0
  4. data/Rakefile +64 -0
  5. data/bin/tmis +4 -0
  6. data/lib/tmis/engine/database.rb +58 -0
  7. data/lib/tmis/engine/export/timetable_exporter.rb +366 -0
  8. data/lib/tmis/engine/import/abstract_spreadsheet.rb +53 -0
  9. data/lib/tmis/engine/import/spreadsheet_roo.rb +136 -0
  10. data/lib/tmis/engine/import/timetable_manager.rb +110 -0
  11. data/lib/tmis/engine/import/timetable_reader.rb +79 -0
  12. data/lib/tmis/engine/mailer/mailer.rb +51 -0
  13. data/lib/tmis/engine/migrations/10_create_speciality_subjects.rb +17 -0
  14. data/lib/tmis/engine/migrations/11_create_emails.rb +10 -0
  15. data/lib/tmis/engine/migrations/12_add_indexes.rb +32 -0
  16. data/lib/tmis/engine/migrations/1_create_groups.rb +11 -0
  17. data/lib/tmis/engine/migrations/2_create_subgroups.rb +10 -0
  18. data/lib/tmis/engine/migrations/3_create_subjects.rb +11 -0
  19. data/lib/tmis/engine/migrations/4_create_cabinets.rb +12 -0
  20. data/lib/tmis/engine/migrations/5_create_lecturers.rb +14 -0
  21. data/lib/tmis/engine/migrations/6_create_studies.rb +15 -0
  22. data/lib/tmis/engine/migrations/7_create_courses.rb +9 -0
  23. data/lib/tmis/engine/migrations/8_create_specialities.rb +9 -0
  24. data/lib/tmis/engine/migrations/9_create_semesters.rb +10 -0
  25. data/lib/tmis/engine/models/cabinet.rb +18 -0
  26. data/lib/tmis/engine/models/course.rb +11 -0
  27. data/lib/tmis/engine/models/email.rb +19 -0
  28. data/lib/tmis/engine/models/group.rb +31 -0
  29. data/lib/tmis/engine/models/lecturer.rb +45 -0
  30. data/lib/tmis/engine/models/semester.rb +4 -0
  31. data/lib/tmis/engine/models/speciality.rb +3 -0
  32. data/lib/tmis/engine/models/speciality_subject.rb +6 -0
  33. data/lib/tmis/engine/models/study.rb +56 -0
  34. data/lib/tmis/engine/models/subgroup.rb +21 -0
  35. data/lib/tmis/engine/models/subject.rb +19 -0
  36. data/lib/tmis/engine/verificator.rb +96 -0
  37. data/lib/tmis/interface/forms/about.rb +24 -0
  38. data/lib/tmis/interface/forms/console.rb +28 -0
  39. data/lib/tmis/interface/forms/debug_console.rb +32 -0
  40. data/lib/tmis/interface/forms/edit_study.rb +110 -0
  41. data/lib/tmis/interface/forms/expand_changes.rb +128 -0
  42. data/lib/tmis/interface/forms/export_general_timetable.rb +68 -0
  43. data/lib/tmis/interface/forms/export_group_timetable.rb +158 -0
  44. data/lib/tmis/interface/forms/export_lecturer_timetable.rb +171 -0
  45. data/lib/tmis/interface/forms/find.rb +71 -0
  46. data/lib/tmis/interface/forms/import.rb +36 -0
  47. data/lib/tmis/interface/forms/settings.rb +125 -0
  48. data/lib/tmis/interface/forms/ui_about.rb +88 -0
  49. data/lib/tmis/interface/forms/ui_console.rb +68 -0
  50. data/lib/tmis/interface/forms/ui_debug_console.rb +82 -0
  51. data/lib/tmis/interface/forms/ui_edit_study.rb +202 -0
  52. data/lib/tmis/interface/forms/ui_expand_changes.rb +134 -0
  53. data/lib/tmis/interface/forms/ui_export_general_timetable.rb +142 -0
  54. data/lib/tmis/interface/forms/ui_export_group_timetable.rb +160 -0
  55. data/lib/tmis/interface/forms/ui_export_lecturer_timetable.rb +160 -0
  56. data/lib/tmis/interface/forms/ui_find.rb +77 -0
  57. data/lib/tmis/interface/forms/ui_import.rb +134 -0
  58. data/lib/tmis/interface/forms/ui_settings.rb +417 -0
  59. data/lib/tmis/interface/mainwindow.rb +933 -0
  60. data/lib/tmis/interface/models/cabinet_table_model.rb +133 -0
  61. data/lib/tmis/interface/models/course_table_model.rb +87 -0
  62. data/lib/tmis/interface/models/group_table_model.rb +190 -0
  63. data/lib/tmis/interface/models/lecturer_table_model.rb +111 -0
  64. data/lib/tmis/interface/models/semester_table_model.rb +137 -0
  65. data/lib/tmis/interface/models/speciality_subject_table_model.rb +288 -0
  66. data/lib/tmis/interface/models/speciality_table_model.rb +87 -0
  67. data/lib/tmis/interface/models/study_table_model.rb +323 -0
  68. data/lib/tmis/interface/models/subgroup_table_model.rb +136 -0
  69. data/lib/tmis/interface/models/subject_table_model.rb +90 -0
  70. data/lib/tmis/interface/ui_mainwindow.rb +928 -0
  71. data/lib/tmis.rb +45 -0
  72. data/spec/config.rb +49 -0
  73. data/spec/database_spec.rb +18 -0
  74. data/spec/export/timetable_exporter_mocks.rb +20 -0
  75. data/spec/export/timetable_exporter_spec.rb +34 -0
  76. data/spec/factories/factories.rb +65 -0
  77. data/spec/import/test_data/raspisanie_2013.csv +104 -0
  78. data/spec/import/timetable_importer_mocks.rb +6 -0
  79. data/spec/import/timetable_manager_spec.rb +16 -0
  80. data/spec/import/timetable_reader_spec.rb +111 -0
  81. data/spec/import/timetable_roo_spec.rb +48 -0
  82. data/spec/mailer/mailer_spec.rb +37 -0
  83. data/spec/mainwindow_spec.rb +18 -0
  84. data/spec/models/cabinet_spec.rb +33 -0
  85. data/spec/models/course_spec.rb +26 -0
  86. data/spec/models/group_spec.rb +33 -0
  87. data/spec/models/lecturer_spec.rb +38 -0
  88. data/spec/models/semester_spec.rb +26 -0
  89. data/spec/models/speciality_spec.rb +26 -0
  90. data/spec/models/speciality_subject_spec.rb +9 -0
  91. data/spec/models/study_spec.rb +9 -0
  92. data/spec/models/subgroup_spec.rb +26 -0
  93. data/spec/models/subject_spec.rb +39 -0
  94. metadata +290 -0
@@ -0,0 +1,158 @@
1
+ # coding: UTF-8
2
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ require 'Qt'
4
+ require 'date'
5
+ require_relative 'settings'
6
+ require_relative 'ui_export_group_timetable'
7
+ require_relative '../../engine/database'
8
+ require_relative '../../engine/models/group'
9
+ require_relative '../../engine/export/timetable_exporter.rb'
10
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
+ require 'contracts'
12
+ #include Contracts
13
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14
+ class ExportGroupTimetableDialog < Qt::Dialog
15
+
16
+ slots 'on_exportButtonBox_accepted()'
17
+ slots 'on_exportButtonBox_rejected()'
18
+ slots 'on_selectAllPushButton_pressed()'
19
+ slots 'on_deselectAllPushButton_pressed()'
20
+ slots 'on_saveCheckBox_toggled(bool)'
21
+
22
+ def initialize(initial_date, parent = nil)
23
+ super parent
24
+ @ui = Ui::ExportGroupTimetableDialog.new
25
+ @ui.setup_ui self
26
+ @ui.dayDateEdit.setDate(Qt::Date.fromString(initial_date.to_s, Qt::ISODate))
27
+ @ui.progressBar.visible = false
28
+ Group.all.each do |g|
29
+ item = Qt::ListWidgetItem.new(g.to_s, @ui.groupsListWidget)
30
+ item.setData(Qt::UserRole, Qt::Variant.new(g.id))
31
+ item.checkState = Qt::Unchecked
32
+ end
33
+ end
34
+
35
+ def on_saveCheckBox_stateChanged
36
+ checkbox_actions(sender, chk, unchk)
37
+ end
38
+
39
+ def on_saveCheckBox_toggled(checked)
40
+ if checked
41
+ if (path = Qt::FileDialog::getExistingDirectory(self, 'Open Directory', '/home', Qt::FileDialog::ShowDirsOnly | Qt::FileDialog::DontResolveSymlinks))
42
+ @ui.folderPathLineEdit.text = path # force_encoding doesn't help because Qt changes the encoding to ASCII anyway
43
+ else
44
+ @ui.folderPathLineEdit.text = Dir.home
45
+ end
46
+ else
47
+ @ui.folderPathLineEdit.text = ''
48
+ end
49
+ end
50
+
51
+ def on_selectAllPushButton_pressed
52
+ @ui.groupsListWidget.count.times{|i| @ui.groupsListWidget.item(i).setCheckState(Qt::Checked) }
53
+ end
54
+
55
+ def on_deselectAllPushButton_pressed
56
+ @ui.groupsListWidget.count.times{|i| @ui.groupsListWidget.item(i).setCheckState(Qt::Unchecked) }
57
+ end
58
+
59
+ def on_exportButtonBox_accepted
60
+ if @ui.modeComboBox.currentIndex == 0
61
+ date = Date.parse(@ui.dayDateEdit.date.toString(Qt::ISODate)).monday
62
+ export(date..date + 5)
63
+ close
64
+ elsif @ui.modeComboBox.currentIndex == 1
65
+ export([Date.parse(@ui.dayDateEdit.date.toString(Qt::ISODate))])
66
+ close
67
+ end
68
+ end
69
+
70
+ def export(dates)
71
+ # TODO распараллелить
72
+ # TODO progressBar в процентах
73
+ @ui.progressBar.visible = true
74
+ @ui.progressBar.setRange(0, @ui.groupsListWidget.count)
75
+ if @ui.saveCheckBox.checkState == Qt::Checked and @ui.mailCheckBox.checkState == Qt::Checked
76
+ @ui.groupsListWidget.count.times do |i|
77
+ @ui.progressBar.setValue(i)
78
+ Qt::Application::processEvents
79
+ if @ui.groupsListWidget.item(i).checkState == Qt::Checked
80
+ id = @ui.groupsListWidget.item(i).data(Qt::UserRole)
81
+ group = Group.where(id: id.to_i).first
82
+ path = @ui.folderPathLineEdit.text.force_encoding('UTF-8')
83
+ if File.writable? path
84
+ filename = File.join(path, "#{group.title}_timetable.xls")
85
+ if File.exist? filename
86
+ File.delete filename
87
+ spreadsheet = SpreadsheetCreater.create filename
88
+ else
89
+ spreadsheet = SpreadsheetCreater.create filename
90
+ end
91
+ TimetableExporter.new(spreadsheet, GroupTimetableExportStratagy.new(dates, group)).export.save
92
+ mail(group, filename)
93
+ end
94
+ end
95
+ end
96
+ elsif @ui.saveCheckBox.checkState == Qt::Checked
97
+ @ui.groupsListWidget.count.times do |i|
98
+ @ui.progressBar.setValue(i)
99
+ Qt::Application::processEvents
100
+ if @ui.groupsListWidget.item(i).checkState == Qt::Checked
101
+ id = @ui.groupsListWidget.item(i).data(Qt::UserRole)
102
+ group = Group.where(id: id.to_i).first
103
+ path = @ui.folderPathLineEdit.text.force_encoding('UTF-8')
104
+ if File.writable? path
105
+ filename = File.join(path, "#{group.title}_timetable.xls")
106
+ if File.exist? filename
107
+ File.delete filename
108
+ spreadsheet = SpreadsheetCreater.create filename
109
+ else
110
+ spreadsheet = SpreadsheetCreater.create filename
111
+ end
112
+ TimetableExporter.new(spreadsheet, GroupTimetableExportStratagy.new(dates, group)).export.save
113
+ mail(group, filename)
114
+ end
115
+ end
116
+ end
117
+ elsif @ui.mailCheckBox.checkState == Qt::Checked
118
+ @ui.groupsListWidget.count.times do |i|
119
+ @ui.progressBar.setValue(i)
120
+ Qt::Application::processEvents
121
+ if @ui.groupsListWidget.item(i).checkState == Qt::Checked
122
+ id = @ui.groupsListWidget.item(i).data(Qt::UserRole)
123
+ group = Group.where(id: id.to_i).first
124
+ filename = Dir.mktmpdir('tmis') + "/#{group.title}_timetable.xls"
125
+ spreadsheet = SpreadsheetCreater.create filename
126
+ TimetableExporter.new(spreadsheet, GroupTimetableExportStratagy.new(dates, group)).export.save
127
+ mail(group, filename)
128
+ end
129
+ end
130
+ end
131
+ # thread.join
132
+ @ui.progressBar.visible = false
133
+ end
134
+
135
+ def mail(group, filename)
136
+ group.emails.select(&:email_valid?).each do |email|
137
+ text = "Здравствуйте, куратор группы #{group.to_s}!\n" +
138
+ "В прикреплённой электронной таблице находится расписание для вашей группы.\n"
139
+ Mailer.new(Settings[:mailer, :email], Settings[:mailer, :password]) do
140
+ from 'tmis@kp11.ru'
141
+ to email.email
142
+ subject 'Расписание'
143
+ body text
144
+ add_file filename
145
+ end.send!
146
+ end
147
+ end
148
+
149
+ def on_exportButtonBox_rejected
150
+ close
151
+ end
152
+
153
+ def show_message(text)
154
+ box = Qt::MessageBox.new
155
+ box.setText text
156
+ box.exec
157
+ end
158
+ end
@@ -0,0 +1,171 @@
1
+ # coding: UTF-8
2
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ require 'Qt'
4
+ require 'date'
5
+ require_relative 'settings'
6
+ require_relative 'ui_export_lecturer_timetable'
7
+ require_relative '../../engine/database'
8
+ require_relative '../../engine/models/lecturer'
9
+ require_relative '../../engine/export/timetable_exporter.rb'
10
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
+ require 'contracts'
12
+ #include Contracts
13
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14
+ class ExportLecturerTimetableDialog < Qt::Dialog
15
+
16
+ slots 'on_exportButtonBox_accepted()'
17
+ slots 'on_exportButtonBox_rejected()'
18
+ slots 'on_selectAllPushButton_pressed()'
19
+ slots 'on_deselectAllPushButton_pressed()'
20
+ slots 'on_saveCheckBox_toggled(bool)'
21
+
22
+ def initialize(initial_date, parent = nil)
23
+ super parent
24
+ @ui = Ui::ExportLecturerTimetableDialog.new
25
+ @ui.setup_ui self
26
+ @ui.dayDateEdit.setDate(Qt::Date.fromString(initial_date.to_s, Qt::ISODate))
27
+ @ui.progressBar.visible = false
28
+ Lecturer.all.each do |l|
29
+ item = Qt::ListWidgetItem.new(l.to_s, @ui.lecturersListWidget)
30
+ item.setData(Qt::UserRole, Qt::Variant.new(l.id))
31
+ item.checkState = Qt::Unchecked
32
+ end
33
+ end
34
+
35
+ def on_saveCheckBox_stateChanged
36
+ checkbox_actions(sender, chk, unchk)
37
+ end
38
+
39
+ def on_saveCheckBox_toggled(checked)
40
+ if checked
41
+ if (path = Qt::FileDialog::getExistingDirectory(self, 'Open Directory', '/home', Qt::FileDialog::ShowDirsOnly | Qt::FileDialog::DontResolveSymlinks))
42
+ @ui.folderPathLineEdit.text = path # force_encoding doesn't help because Qt changes the encoding to ASCII anyway
43
+ else
44
+ @ui.folderPathLineEdit.text = Dir.home
45
+ end
46
+ else
47
+ @ui.folderPathLineEdit.text = ''
48
+ end
49
+ end
50
+
51
+ def on_selectAllPushButton_pressed
52
+ @ui.lecturersListWidget.count.times{|i| @ui.lecturersListWidget.item(i).setCheckState(Qt::Checked) }
53
+ end
54
+
55
+ def on_deselectAllPushButton_pressed
56
+ @ui.lecturersListWidget.count.times{|i| @ui.lecturersListWidget.item(i).setCheckState(Qt::Unchecked) }
57
+ end
58
+
59
+ def on_exportButtonBox_accepted
60
+ if @ui.modeComboBox.currentIndex == 0
61
+ date = Date.parse(@ui.dayDateEdit.date.toString(Qt::ISODate)).monday
62
+ export(date..date + 5)
63
+ close
64
+ elsif @ui.modeComboBox.currentIndex == 1
65
+ export([Date.parse(@ui.dayDateEdit.date.toString(Qt::ISODate))])
66
+ close
67
+ end
68
+ end
69
+
70
+ def export(dates)
71
+ # TODO распараллелить
72
+ # TODO progressBar в процентах
73
+ @ui.progressBar.visible = true
74
+ @ui.progressBar.setRange(0, @ui.lecturersListWidget.count)
75
+ if @ui.saveCheckBox.checkState == Qt::Checked and @ui.mailCheckBox.checkState == Qt::Checked
76
+ #if !@ui.folderPathLineEdit.text.empty? && Dir.exist?(File.expand_path(@ui.folderPathLineEdit.text.force_encoding('UTF-8')))
77
+ @ui.lecturersListWidget.count.times do |i|
78
+ @ui.progressBar.setValue(i)
79
+ Qt::Application::processEvents
80
+ if @ui.lecturersListWidget.item(i).checkState == Qt::Checked
81
+ id = @ui.lecturersListWidget.item(i).data(Qt::UserRole)
82
+ lecturer = Lecturer.where(id: id.to_i).first
83
+ path = @ui.folderPathLineEdit.text.force_encoding('UTF-8')
84
+ if File.writable? path
85
+ filename = File.join(path, "#{lecturer.surname}_timetable.xls")
86
+ if File.exist? filename
87
+ File.delete filename
88
+ spreadsheet = SpreadsheetCreater.create filename
89
+ else
90
+ spreadsheet = SpreadsheetCreater.create filename
91
+ end
92
+ TimetableExporter2.new(spreadsheet, LecturerTimetableExportStratagy2.new(dates, lecturer)).export.save
93
+ mail(lecturer, filename)
94
+ end
95
+ end
96
+ end
97
+ #else
98
+ # show_message 'Директория не существует выберите другую.'
99
+ #end
100
+ elsif @ui.saveCheckBox.checkState == Qt::Checked
101
+ @ui.lecturersListWidget.count.times do |i|
102
+ @ui.progressBar.setValue(i)
103
+ Qt::Application::processEvents
104
+ if @ui.lecturersListWidget.item(i).checkState == Qt::Checked
105
+ id = @ui.lecturersListWidget.item(i).data(Qt::UserRole)
106
+ lecturer = Lecturer.where(id: id.to_i).first
107
+ path = @ui.folderPathLineEdit.text.force_encoding('UTF-8')
108
+ if File.writable? path
109
+ filename = File.join(path, "#{lecturer.surname}_timetable.xls")
110
+ if File.exist? filename
111
+ File.delete filename
112
+ spreadsheet = SpreadsheetCreater.create filename
113
+ else
114
+ spreadsheet = SpreadsheetCreater.create filename
115
+ end
116
+ TimetableExporter2.new(spreadsheet, LecturerTimetableExportStratagy2.new(dates, lecturer)).export.save
117
+ mail(lecturer, filename)
118
+ end
119
+ end
120
+ end
121
+ elsif @ui.mailCheckBox.checkState == Qt::Checked
122
+ @ui.lecturersListWidget.count.times do |i|
123
+ @ui.progressBar.setValue(i)
124
+ Qt::Application::processEvents
125
+ if @ui.lecturersListWidget.item(i).checkState == Qt::Checked
126
+ id = @ui.lecturersListWidget.item(i).data(Qt::UserRole)
127
+ lecturer = Lecturer.where(id: id.to_i).first
128
+ filename = Dir.mktmpdir('tmis') + "/#{lecturer.surname}_timetable.xls"
129
+ spreadsheet = SpreadsheetCreater.create filename
130
+ TimetableExporter2.new(spreadsheet, LecturerTimetableExportStratagy2.new(dates, lecturer)).export.save
131
+ mail(lecturer, filename)
132
+ end
133
+ end
134
+ end
135
+ # thread.join
136
+ @ui.progressBar.visible = false
137
+ end
138
+
139
+ def mail(lecturer, filename)
140
+ lecturer.emails.select(&:email_valid?).each do |email|
141
+ text = "Здравствуйте, #{lecturer.to_s}! Ваши пары на этой неделе:\n\n"
142
+ grouped = lecturer.studies.group(:date, :number).group_by(&:date)
143
+ grouped.each do |date, studies|
144
+ text += "Дата: #{date}\n\n"
145
+ studies.each do |s|
146
+ text += "\t Номер: #{s.number}, группа: #{s.groupable.to_s}, предмет #{s.subject.title}, кабинет: #{s.cabinet.title}\n"
147
+ end
148
+ end
149
+ text += "\nИтого пар: #{lecturer.studies.count}\n"
150
+ # lecturer.emails.map do
151
+ Mailer.new(Settings[:mailer, :email], Settings[:mailer, :password]) do
152
+ from 'tmis@kp11.ru'
153
+ to email.email
154
+ subject 'Расписание'
155
+ body text
156
+ add_file filename
157
+ end.send!
158
+ #add_file :filename => 'timetable.xls', :content => File.read(filename, "r:UTF-8")
159
+ end
160
+ end
161
+
162
+ def on_exportButtonBox_rejected
163
+ close
164
+ end
165
+
166
+ def show_message(text)
167
+ box = Qt::MessageBox.new
168
+ box.setText text
169
+ box.exec
170
+ end
171
+ end
@@ -0,0 +1,71 @@
1
+ # coding: UTF-8
2
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ require 'Qt'
4
+ require_relative 'ui_find'
5
+ require_relative '../../engine/database'
6
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
+ require 'contracts'
8
+ #include Contracts
9
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
+ class FindDialog < Qt::Dialog
11
+
12
+ def initialize(entity, parent = nil)
13
+ super parent
14
+ @main = parent
15
+ @ui = Ui::FindDialog.new
16
+ @ui.setup_ui self
17
+ @entity = entity
18
+ case @entity
19
+ when :lecturer
20
+ @ui.findByLabel.text = "Фамилия преподавателя:"
21
+ Lecturer.all.sort_by(&:surname).each{|x| @ui.findByComboBox.addItem(x.surname, x.id.to_v)}
22
+ @ui.findByComboBox.setCurrentIndex(0)
23
+ when :subject
24
+ @ui.findByLabel.text = "Название предмета:"
25
+ Subject.all.sort_by(&:title).each{|x| @ui.findByComboBox.addItem(x.title, x.id.to_v)}
26
+ @ui.findByComboBox.setCurrentIndex(0)
27
+ when :cabinet
28
+ @ui.findByLabel.text = "Название кабинета:"
29
+ Cabinet.all.sort_by(&:title).each{|x| @ui.findByComboBox.addItem(x.title, x.id.to_v)}
30
+ @ui.findByComboBox.setCurrentIndex(0)
31
+ else
32
+ raise ArgumentError
33
+ end
34
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Ok), SIGNAL('clicked()')){ ok }
35
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Cancel), SIGNAL('clicked()')){ cancel }
36
+ end
37
+
38
+ def ok
39
+ @main.study_table_models.each do |model|
40
+ model.cancelColoring
41
+ end
42
+ case @entity
43
+ when :lecturer
44
+ studies = Study.where(lecturer_id: @ui.findByComboBox.itemData(@ui.findByComboBox.currentIndex).to_i)
45
+ when :subject
46
+ studies = Study.where(subject_id: @ui.findByComboBox.itemData(@ui.findByComboBox.currentIndex).to_i)
47
+ when :cabinet
48
+ studies = Study.where(cabinet_id: @ui.findByComboBox.itemData(@ui.findByComboBox.currentIndex).to_i)
49
+ else
50
+ raise ArgumentError
51
+ end
52
+ studies.each do |study|
53
+ @main.study_table_models.each do |model|
54
+ model.setColor(study.id, Qt::green)
55
+ end
56
+ end
57
+ end
58
+
59
+ def cancel
60
+ @main.study_table_models.each do |model|
61
+ model.cancelColoring
62
+ end
63
+ close
64
+ end
65
+
66
+ def show_message(text)
67
+ box = Qt::MessageBox.new
68
+ box.setText text
69
+ box.exec
70
+ end
71
+ end
@@ -0,0 +1,36 @@
1
+ # coding: UTF-8
2
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ require 'Qt'
4
+ require 'date'
5
+ require_relative 'ui_import'
6
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
+ require 'contracts'
8
+ #include Contracts
9
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
+ class ImportDialog < Qt::Dialog
11
+
12
+ attr_reader :params
13
+
14
+ slots 'on_buttonBox_accepted()'
15
+ slots 'on_buttonBox_rejected()'
16
+
17
+ def initialize(initial_date, parent = nil)
18
+ super parent
19
+ @ui = Ui::ImportDialog.new
20
+ @ui.setup_ui self
21
+ monday = Qt::Date.fromString(initial_date.monday.to_s, Qt::ISODate)
22
+ @ui.dateEdit.setDate(monday)
23
+ @params = {}
24
+ end
25
+
26
+ def on_buttonBox_accepted
27
+ date = Date.parse(@ui.dateEdit.date.toString(Qt::ISODate)).monday
28
+ @params[:sheet] = @ui.sheetNumberSpinBox.value
29
+ @params[:date] = date
30
+ close
31
+ end
32
+
33
+ def on_buttonBox_rejected
34
+ close
35
+ end
36
+ end
@@ -0,0 +1,125 @@
1
+ # coding: UTF-8
2
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
+ require 'Qt'
4
+ require_relative 'ui_settings'
5
+ require_relative '../../engine/mailer/mailer.rb'
6
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
+ require 'contracts'
8
+ #include Contracts
9
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
+ class Settings
11
+
12
+ @@settings = Qt::Settings.new('settings.ini', 'Qt::Settings::IniFormat')
13
+
14
+ #Contract Symbol, Symbol => String
15
+ def self.[](group, key)
16
+ @@settings.beginGroup group.to_s
17
+ result = @@settings.value key.to_s
18
+ @@settings.endGroup()
19
+ result.value.to_s.force_encoding('UTF-8')
20
+ end
21
+
22
+ #Contract Symbol, Symbol, Any => Any
23
+ def self.[]=(group, key, value)
24
+ @@settings.beginGroup group.to_s
25
+ @@settings.setValue(key.to_s, Qt::Variant.new(value))
26
+ @@settings.endGroup()
27
+ @@settings.sync
28
+ end
29
+
30
+ def self.reset!(group)
31
+ case group
32
+ when :mailer
33
+ self[:mailer, :email] = 'email@example.com'
34
+ self[:mailer, :password] = '12345'
35
+ when :stubs
36
+ self[:stubs, :lecturer] = 'Вакансия'
37
+ self[:stubs, :cabinet] = 'Не назначен'
38
+ self[:stubs, :subject] = 'Не назначен'
39
+ else
40
+ raise ArgumentError, 'No such settings group!'
41
+ end
42
+ end
43
+
44
+ def self.set_defaults_if_first_run
45
+ if Settings[:app, :first_run].empty?
46
+ Settings[:app, :first_run] = 'false'
47
+ self.reset! :mailer
48
+ self.reset! :stubs
49
+ end
50
+ end
51
+ end
52
+
53
+ class SettingsDialog < Qt::Dialog
54
+
55
+ slots 'apply()'
56
+ slots 'ok()'
57
+ slots 'restore()'
58
+ slots 'help()'
59
+
60
+ def initialize(parent = nil)
61
+ super(parent)
62
+ @ui = Ui::SettingsDialog.new
63
+ @ui.setup_ui self
64
+ @ui.stackedWidget.setCurrentIndex(0)
65
+ setup
66
+ connect(@ui.actionsListWidget, SIGNAL('currentRowChanged(int)'), @ui.stackedWidget, SLOT('setCurrentIndex(int)'))
67
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Ok), SIGNAL('clicked()'), self, SLOT('ok()'))
68
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Apply), SIGNAL('clicked()'), self, SLOT('apply()'))
69
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Help), SIGNAL('clicked()'), self, SLOT('help()'))
70
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::RestoreDefaults), SIGNAL('clicked()'), self, SLOT('restore()'))
71
+ connect(@ui.buttonBox.button(Qt::DialogButtonBox::Cancel), SIGNAL('clicked()')){ close }
72
+
73
+ end
74
+
75
+ def setup
76
+ @ui.emailLineEdit.text = Settings[:mailer, :email]
77
+ @ui.passwordLineEdit.text = Settings[:mailer, :password]
78
+ @ui.lecturerStubLineEdit.text = Settings[:stubs, :lecturer]
79
+ @ui.cabinetStubLineEdit.text = Settings[:stubs, :cabinet]
80
+ @ui.subjectStubLineEdit.text = Settings[:stubs, :subject]
81
+ end
82
+
83
+ def apply
84
+ if Mailer.email_valid? @ui.emailLineEdit.text
85
+ Settings[:mailer, :email] = @ui.emailLineEdit.text.force_encoding('UTF-8')
86
+ Settings[:mailer, :password] = @ui.passwordLineEdit.text.force_encoding('UTF-8')
87
+ else
88
+ show_message 'Email имеет неправильный формат!'
89
+ return false
90
+ end
91
+ Settings[:stubs, :lecturer] = @ui.lecturerStubLineEdit.text.force_encoding('UTF-8')
92
+ Settings[:stubs, :cabinet] = @ui.cabinetStubLineEdit.text.force_encoding('UTF-8')
93
+ Settings[:stubs, :subject] = @ui.subjectStubLineEdit.text.force_encoding('UTF-8')
94
+ return true
95
+ end
96
+
97
+ def ok
98
+ close if apply
99
+ end
100
+
101
+ def restore
102
+ #case @ui.stackedWidget.currentWidget.objectName
103
+ #when 'database'
104
+ # Settings.reset! :stubs
105
+ #when 'email'
106
+ # Settings.reset! :mailer
107
+ #when 'interface'
108
+ #when 'verify'
109
+ #when 'export'
110
+ #when 'import'
111
+ #else
112
+ #end
113
+ Settings.reset! :stubs
114
+ Settings.reset! :mailer
115
+ end
116
+
117
+ def help
118
+ end
119
+
120
+ def show_message(text)
121
+ box = Qt::MessageBox.new(self)
122
+ box.setText text
123
+ box.exec
124
+ end
125
+ end
@@ -0,0 +1,88 @@
1
+ =begin
2
+ ** Form generated from reading ui file 'about.ui'
3
+ **
4
+ ** Created: Wed Sep 4 00:30:33 2013
5
+ ** by: Qt User Interface Compiler version 4.8.5
6
+ **
7
+ ** WARNING! All changes made in this file will be lost when recompiling ui file!
8
+ =end
9
+
10
+ class Ui_AboutDialog
11
+ attr_reader :gridLayout_2
12
+ attr_reader :gridLayout
13
+ attr_reader :horizontalLayout
14
+ attr_reader :line
15
+ attr_reader :textBrowser
16
+ attr_reader :buttonBox
17
+
18
+ def setupUi(aboutDialog)
19
+ if aboutDialog.objectName.nil?
20
+ aboutDialog.objectName = "aboutDialog"
21
+ end
22
+ aboutDialog.resize(562, 271)
23
+ @gridLayout_2 = Qt::GridLayout.new(aboutDialog)
24
+ @gridLayout_2.objectName = "gridLayout_2"
25
+ @gridLayout = Qt::GridLayout.new()
26
+ @gridLayout.objectName = "gridLayout"
27
+ @horizontalLayout = Qt::HBoxLayout.new()
28
+ @horizontalLayout.objectName = "horizontalLayout"
29
+ @line = Qt::Frame.new(aboutDialog)
30
+ @line.objectName = "line"
31
+ @line.setFrameShape(Qt::Frame::VLine)
32
+ @line.setFrameShadow(Qt::Frame::Sunken)
33
+
34
+ @horizontalLayout.addWidget(@line)
35
+
36
+ @textBrowser = Qt::TextBrowser.new(aboutDialog)
37
+ @textBrowser.objectName = "textBrowser"
38
+ @textBrowser.enabled = true
39
+ @textBrowser.styleSheet = "background: transparent;"
40
+ @textBrowser.frameShape = Qt::Frame::NoFrame
41
+ @textBrowser.frameShadow = Qt::Frame::Plain
42
+
43
+ @horizontalLayout.addWidget(@textBrowser)
44
+
45
+
46
+ @gridLayout.addLayout(@horizontalLayout, 1, 0, 1, 1)
47
+
48
+ @buttonBox = Qt::DialogButtonBox.new(aboutDialog)
49
+ @buttonBox.objectName = "buttonBox"
50
+ @buttonBox.orientation = Qt::Horizontal
51
+ @buttonBox.standardButtons = Qt::DialogButtonBox::Cancel
52
+
53
+ @gridLayout.addWidget(@buttonBox, 2, 0, 1, 1)
54
+
55
+
56
+ @gridLayout_2.addLayout(@gridLayout, 1, 0, 1, 1)
57
+
58
+
59
+ retranslateUi(aboutDialog)
60
+ Qt::Object.connect(@buttonBox, SIGNAL('rejected()'), aboutDialog, SLOT('close()'))
61
+
62
+ Qt::MetaObject.connectSlotsByName(aboutDialog)
63
+ end # setupUi
64
+
65
+ def setup_ui(aboutDialog)
66
+ setupUi(aboutDialog)
67
+ end
68
+
69
+ def retranslateUi(aboutDialog)
70
+ aboutDialog.windowTitle = Qt::Application.translate("AboutDialog", "\320\236 \320\277\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\265", nil, Qt::Application::UnicodeUTF8)
71
+ @textBrowser.html = Qt::Application.translate("AboutDialog", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" \
72
+ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" \
73
+ "p, li { white-space: pre-wrap; }\n" \
74
+ "</style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\">\n" \
75
+ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>", nil, Qt::Application::UnicodeUTF8)
76
+ end # retranslateUi
77
+
78
+ def retranslate_ui(aboutDialog)
79
+ retranslateUi(aboutDialog)
80
+ end
81
+
82
+ end
83
+
84
+ module Ui
85
+ class AboutDialog < Ui_AboutDialog
86
+ end
87
+ end # module Ui
88
+