tmis 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +674 -0
- data/README.md +44 -0
- data/Rakefile +64 -0
- data/bin/tmis +4 -0
- data/lib/tmis/engine/database.rb +58 -0
- data/lib/tmis/engine/export/timetable_exporter.rb +366 -0
- data/lib/tmis/engine/import/abstract_spreadsheet.rb +53 -0
- data/lib/tmis/engine/import/spreadsheet_roo.rb +136 -0
- data/lib/tmis/engine/import/timetable_manager.rb +110 -0
- data/lib/tmis/engine/import/timetable_reader.rb +79 -0
- data/lib/tmis/engine/mailer/mailer.rb +51 -0
- data/lib/tmis/engine/migrations/10_create_speciality_subjects.rb +17 -0
- data/lib/tmis/engine/migrations/11_create_emails.rb +10 -0
- data/lib/tmis/engine/migrations/12_add_indexes.rb +32 -0
- data/lib/tmis/engine/migrations/1_create_groups.rb +11 -0
- data/lib/tmis/engine/migrations/2_create_subgroups.rb +10 -0
- data/lib/tmis/engine/migrations/3_create_subjects.rb +11 -0
- data/lib/tmis/engine/migrations/4_create_cabinets.rb +12 -0
- data/lib/tmis/engine/migrations/5_create_lecturers.rb +14 -0
- data/lib/tmis/engine/migrations/6_create_studies.rb +15 -0
- data/lib/tmis/engine/migrations/7_create_courses.rb +9 -0
- data/lib/tmis/engine/migrations/8_create_specialities.rb +9 -0
- data/lib/tmis/engine/migrations/9_create_semesters.rb +10 -0
- data/lib/tmis/engine/models/cabinet.rb +18 -0
- data/lib/tmis/engine/models/course.rb +11 -0
- data/lib/tmis/engine/models/email.rb +19 -0
- data/lib/tmis/engine/models/group.rb +31 -0
- data/lib/tmis/engine/models/lecturer.rb +45 -0
- data/lib/tmis/engine/models/semester.rb +4 -0
- data/lib/tmis/engine/models/speciality.rb +3 -0
- data/lib/tmis/engine/models/speciality_subject.rb +6 -0
- data/lib/tmis/engine/models/study.rb +56 -0
- data/lib/tmis/engine/models/subgroup.rb +21 -0
- data/lib/tmis/engine/models/subject.rb +19 -0
- data/lib/tmis/engine/verificator.rb +96 -0
- data/lib/tmis/interface/forms/about.rb +24 -0
- data/lib/tmis/interface/forms/console.rb +28 -0
- data/lib/tmis/interface/forms/debug_console.rb +32 -0
- data/lib/tmis/interface/forms/edit_study.rb +110 -0
- data/lib/tmis/interface/forms/expand_changes.rb +128 -0
- data/lib/tmis/interface/forms/export_general_timetable.rb +68 -0
- data/lib/tmis/interface/forms/export_group_timetable.rb +158 -0
- data/lib/tmis/interface/forms/export_lecturer_timetable.rb +171 -0
- data/lib/tmis/interface/forms/find.rb +71 -0
- data/lib/tmis/interface/forms/import.rb +36 -0
- data/lib/tmis/interface/forms/settings.rb +125 -0
- data/lib/tmis/interface/forms/ui_about.rb +88 -0
- data/lib/tmis/interface/forms/ui_console.rb +68 -0
- data/lib/tmis/interface/forms/ui_debug_console.rb +82 -0
- data/lib/tmis/interface/forms/ui_edit_study.rb +202 -0
- data/lib/tmis/interface/forms/ui_expand_changes.rb +134 -0
- data/lib/tmis/interface/forms/ui_export_general_timetable.rb +142 -0
- data/lib/tmis/interface/forms/ui_export_group_timetable.rb +160 -0
- data/lib/tmis/interface/forms/ui_export_lecturer_timetable.rb +160 -0
- data/lib/tmis/interface/forms/ui_find.rb +77 -0
- data/lib/tmis/interface/forms/ui_import.rb +134 -0
- data/lib/tmis/interface/forms/ui_settings.rb +417 -0
- data/lib/tmis/interface/mainwindow.rb +933 -0
- data/lib/tmis/interface/models/cabinet_table_model.rb +133 -0
- data/lib/tmis/interface/models/course_table_model.rb +87 -0
- data/lib/tmis/interface/models/group_table_model.rb +190 -0
- data/lib/tmis/interface/models/lecturer_table_model.rb +111 -0
- data/lib/tmis/interface/models/semester_table_model.rb +137 -0
- data/lib/tmis/interface/models/speciality_subject_table_model.rb +288 -0
- data/lib/tmis/interface/models/speciality_table_model.rb +87 -0
- data/lib/tmis/interface/models/study_table_model.rb +323 -0
- data/lib/tmis/interface/models/subgroup_table_model.rb +136 -0
- data/lib/tmis/interface/models/subject_table_model.rb +90 -0
- data/lib/tmis/interface/ui_mainwindow.rb +928 -0
- data/lib/tmis.rb +45 -0
- data/spec/config.rb +49 -0
- data/spec/database_spec.rb +18 -0
- data/spec/export/timetable_exporter_mocks.rb +20 -0
- data/spec/export/timetable_exporter_spec.rb +34 -0
- data/spec/factories/factories.rb +65 -0
- data/spec/import/test_data/raspisanie_2013.csv +104 -0
- data/spec/import/timetable_importer_mocks.rb +6 -0
- data/spec/import/timetable_manager_spec.rb +16 -0
- data/spec/import/timetable_reader_spec.rb +111 -0
- data/spec/import/timetable_roo_spec.rb +48 -0
- data/spec/mailer/mailer_spec.rb +37 -0
- data/spec/mainwindow_spec.rb +18 -0
- data/spec/models/cabinet_spec.rb +33 -0
- data/spec/models/course_spec.rb +26 -0
- data/spec/models/group_spec.rb +33 -0
- data/spec/models/lecturer_spec.rb +38 -0
- data/spec/models/semester_spec.rb +26 -0
- data/spec/models/speciality_spec.rb +26 -0
- data/spec/models/speciality_subject_spec.rb +9 -0
- data/spec/models/study_spec.rb +9 -0
- data/spec/models/subgroup_spec.rb +26 -0
- data/spec/models/subject_spec.rb +39 -0
- metadata +290 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
3
|
+
require_relative '../../engine/models/subgroup'
|
4
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
5
|
+
class SubgroupTableModel < Qt::AbstractTableModel
|
6
|
+
|
7
|
+
def initialize(subgroups, parent)
|
8
|
+
super()
|
9
|
+
@subgroups = subgroups
|
10
|
+
@view = parent
|
11
|
+
@GroupComboBoxDelegate = GroupComboBoxDelegate.new(self)
|
12
|
+
@view.setItemDelegateForColumn(1, @GroupComboBoxDelegate)
|
13
|
+
end
|
14
|
+
|
15
|
+
def refresh
|
16
|
+
@subgroups = Subgroup.all
|
17
|
+
@GroupComboBoxDelegate.setup
|
18
|
+
emit layoutChanged()
|
19
|
+
end
|
20
|
+
|
21
|
+
def rowCount(parent)
|
22
|
+
@subgroups.size
|
23
|
+
end
|
24
|
+
|
25
|
+
def columnCount(parent)
|
26
|
+
2
|
27
|
+
end
|
28
|
+
|
29
|
+
def data(index, role = Qt::DisplayRole)
|
30
|
+
subgroup = @subgroups[index.row]
|
31
|
+
default = Qt::Variant.new
|
32
|
+
case role
|
33
|
+
when Qt::DisplayRole
|
34
|
+
case index.column
|
35
|
+
when 0
|
36
|
+
subgroup.number
|
37
|
+
when 1
|
38
|
+
subgroup.group.try(:title)
|
39
|
+
else
|
40
|
+
raise "invalid column #{index.column}"
|
41
|
+
end.try(:to_v) || default
|
42
|
+
when Qt::EditRole
|
43
|
+
case index.column
|
44
|
+
when 0
|
45
|
+
subgroup.number
|
46
|
+
when 1
|
47
|
+
subgroup.group_id
|
48
|
+
else
|
49
|
+
raise "invalid column #{index.column}"
|
50
|
+
end.try(:to_v) || default
|
51
|
+
else
|
52
|
+
default
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def headerData(section, orientation, role = Qt::DisplayRole)
|
57
|
+
invalid = Qt::Variant.new
|
58
|
+
return invalid unless role == Qt::DisplayRole
|
59
|
+
v = case orientation
|
60
|
+
when Qt::Horizontal
|
61
|
+
%w(Номер Группа)[section]
|
62
|
+
else
|
63
|
+
''
|
64
|
+
end
|
65
|
+
Qt::Variant.new(v)
|
66
|
+
end
|
67
|
+
|
68
|
+
def flags(index)
|
69
|
+
Qt::ItemIsEditable | super(index)
|
70
|
+
end
|
71
|
+
|
72
|
+
def setData(index, variant, role = Qt::EditRole)
|
73
|
+
if index.valid? and role == Qt::EditRole
|
74
|
+
subgroup = @subgroups[index.row]
|
75
|
+
case index.column
|
76
|
+
when 0
|
77
|
+
subgroup.number = variant.toInt
|
78
|
+
when 1
|
79
|
+
subgroup.group_id = variant.toInt
|
80
|
+
else
|
81
|
+
raise "invalid column #{index.column}"
|
82
|
+
end
|
83
|
+
subgroup.save
|
84
|
+
emit dataChanged(index, index)
|
85
|
+
true
|
86
|
+
else
|
87
|
+
false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def insert_new
|
92
|
+
@subgroups.prepend(Subgroup.new)
|
93
|
+
emit layoutChanged()
|
94
|
+
end
|
95
|
+
|
96
|
+
def remove_current
|
97
|
+
if @view.currentIndex.valid?
|
98
|
+
@subgroups[@view.currentIndex.row].try(:destroy)
|
99
|
+
@subgroups.delete_at(@view.currentIndex.row)
|
100
|
+
emit layoutChanged()
|
101
|
+
@view.currentIndex = createIndex(-1, -1)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
class GroupComboBoxDelegate < Qt::ItemDelegate
|
108
|
+
def initialize(parent)
|
109
|
+
super
|
110
|
+
setup
|
111
|
+
end
|
112
|
+
|
113
|
+
def setup
|
114
|
+
@groups = Group.all.sort_by(&:title_for_sort)
|
115
|
+
end
|
116
|
+
|
117
|
+
def createEditor(parent, option, index)
|
118
|
+
editor = Qt::ComboBox.new(parent)
|
119
|
+
@groups.each{ |x| editor.addItem(x.title.to_s, x.id.to_v) }
|
120
|
+
editor
|
121
|
+
end
|
122
|
+
|
123
|
+
def setEditorData(editor, index)
|
124
|
+
value = index.model.data(index, Qt::EditRole)
|
125
|
+
editor.setCurrentIndex(editor.findData(value))
|
126
|
+
end
|
127
|
+
|
128
|
+
def setModelData(editor, model, index)
|
129
|
+
value = editor.itemData(editor.currentIndex)
|
130
|
+
model.setData(index, value, Qt::EditRole)
|
131
|
+
end
|
132
|
+
|
133
|
+
def updateEditorGeometry(editor, option, index)
|
134
|
+
editor.setGeometry(option.rect)
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
3
|
+
require_relative '../../engine/models/subject'
|
4
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
5
|
+
class SubjectTableModel < Qt::AbstractTableModel
|
6
|
+
|
7
|
+
def initialize(subjects, parent)
|
8
|
+
super()
|
9
|
+
@subjects = subjects
|
10
|
+
@view = parent
|
11
|
+
end
|
12
|
+
|
13
|
+
def refresh
|
14
|
+
@subjects = Subject.all
|
15
|
+
emit layoutChanged()
|
16
|
+
end
|
17
|
+
|
18
|
+
def rowCount(parent)
|
19
|
+
@subjects.size
|
20
|
+
end
|
21
|
+
|
22
|
+
def columnCount(parent)
|
23
|
+
1
|
24
|
+
end
|
25
|
+
|
26
|
+
def data(index, role = Qt::DisplayRole)
|
27
|
+
invalid = Qt::Variant.new
|
28
|
+
return invalid unless role == Qt::DisplayRole or role == Qt::EditRole
|
29
|
+
subject = @subjects[index.row]
|
30
|
+
return invalid if subject.nil?
|
31
|
+
v = case index.column
|
32
|
+
when 0
|
33
|
+
subject.title
|
34
|
+
else
|
35
|
+
raise "invalid column #{index.column}"
|
36
|
+
end || ''
|
37
|
+
Qt::Variant.new(v)
|
38
|
+
end
|
39
|
+
|
40
|
+
def headerData(section, orientation, role = Qt::DisplayRole)
|
41
|
+
invalid = Qt::Variant.new
|
42
|
+
return invalid unless role == Qt::DisplayRole
|
43
|
+
v = case orientation
|
44
|
+
when Qt::Horizontal
|
45
|
+
%w(Название)[section]
|
46
|
+
else
|
47
|
+
''
|
48
|
+
end
|
49
|
+
Qt::Variant.new(v)
|
50
|
+
end
|
51
|
+
|
52
|
+
def flags(index)
|
53
|
+
Qt::ItemIsEditable | super(index)
|
54
|
+
end
|
55
|
+
|
56
|
+
def setData(index, variant, role = Qt::EditRole)
|
57
|
+
if index.valid? and role == Qt::EditRole
|
58
|
+
subject = @subjects[index.row]
|
59
|
+
case index.column
|
60
|
+
when 0
|
61
|
+
subject.title = variant.toString.force_encoding('UTF-8')
|
62
|
+
else
|
63
|
+
raise "invalid column #{index.column}"
|
64
|
+
end
|
65
|
+
subject.save
|
66
|
+
emit dataChanged(index, index)
|
67
|
+
true
|
68
|
+
else
|
69
|
+
false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def insert_new
|
74
|
+
@subjects.prepend(Subject.new)
|
75
|
+
emit layoutChanged()
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_current
|
79
|
+
if @view.currentIndex.valid?
|
80
|
+
subject = @subjects[@view.currentIndex.row]
|
81
|
+
unless subject.stub
|
82
|
+
subject.try(:destroy)
|
83
|
+
@subjects.delete_at(@view.currentIndex.row)
|
84
|
+
emit layoutChanged()
|
85
|
+
@view.currentIndex = createIndex(-1, -1)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|