tmis 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,933 @@
|
|
|
1
|
+
# coding: UTF-8
|
|
2
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
3
|
+
# Copyright (C) 2013 Vladislav Mileshkin
|
|
4
|
+
#
|
|
5
|
+
# This file is part of TMIS.
|
|
6
|
+
#
|
|
7
|
+
# TMIS is free software: you can redistribute it and/or modify
|
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
# (at your option) any later version.
|
|
11
|
+
#
|
|
12
|
+
# TMIS is distributed in the hope that it will be useful,
|
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# GNU General Public License for more details.
|
|
16
|
+
#
|
|
17
|
+
# You should have received a copy of the GNU General Public License
|
|
18
|
+
# along with TMIS. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
20
|
+
require 'Qt'
|
|
21
|
+
require 'mail'
|
|
22
|
+
require 'tmpdir'
|
|
23
|
+
require 'fileutils'
|
|
24
|
+
#require '#Contracts'
|
|
25
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
26
|
+
require_relative '../engine/database'
|
|
27
|
+
require_relative '../engine/verificator'
|
|
28
|
+
require_relative '../engine/import/timetable_manager'
|
|
29
|
+
require_relative '../engine/import/timetable_reader'
|
|
30
|
+
require_relative '../engine/import/spreadsheet_roo'
|
|
31
|
+
require_relative '../engine/export/timetable_exporter.rb'
|
|
32
|
+
require_relative '../engine/mailer/mailer'
|
|
33
|
+
require_relative '../engine/models/cabinet'
|
|
34
|
+
require_relative '../engine/models/course'
|
|
35
|
+
require_relative '../engine/models/group'
|
|
36
|
+
require_relative '../engine/models/lecturer'
|
|
37
|
+
require_relative '../engine/models/semester'
|
|
38
|
+
require_relative '../engine/models/speciality'
|
|
39
|
+
require_relative '../engine/models/speciality_subject'
|
|
40
|
+
require_relative '../engine/models/study'
|
|
41
|
+
require_relative '../engine/models/subject'
|
|
42
|
+
require_relative '../engine/models/subgroup'
|
|
43
|
+
require_relative 'ui_mainwindow'
|
|
44
|
+
require_relative 'forms/about'
|
|
45
|
+
require_relative 'forms/find'
|
|
46
|
+
require_relative 'forms/settings'
|
|
47
|
+
require_relative 'forms/import'
|
|
48
|
+
require_relative 'forms/console'
|
|
49
|
+
require_relative 'forms/debug_console'
|
|
50
|
+
require_relative 'forms/export_general_timetable'
|
|
51
|
+
require_relative 'forms/export_lecturer_timetable'
|
|
52
|
+
require_relative 'forms/export_group_timetable'
|
|
53
|
+
require_relative 'forms/expand_changes'
|
|
54
|
+
require_relative 'models/cabinet_table_model'
|
|
55
|
+
require_relative 'models/course_table_model'
|
|
56
|
+
require_relative 'models/group_table_model'
|
|
57
|
+
require_relative 'models/lecturer_table_model'
|
|
58
|
+
require_relative 'models/semester_table_model'
|
|
59
|
+
require_relative 'models/speciality_table_model'
|
|
60
|
+
require_relative 'models/speciality_subject_table_model'
|
|
61
|
+
require_relative 'models/study_table_model'
|
|
62
|
+
require_relative 'models/subject_table_model'
|
|
63
|
+
require_relative 'models/subgroup_table_model'
|
|
64
|
+
#~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
65
|
+
#class Object
|
|
66
|
+
# def to_v
|
|
67
|
+
# Qt::Variant.new object_id
|
|
68
|
+
# end
|
|
69
|
+
#end
|
|
70
|
+
#
|
|
71
|
+
#class Qt::Variant
|
|
72
|
+
# def to_o
|
|
73
|
+
# ObjectSpace._id2ref to_int
|
|
74
|
+
# end
|
|
75
|
+
#end
|
|
76
|
+
|
|
77
|
+
class Object
|
|
78
|
+
def to_v
|
|
79
|
+
Qt::Variant.new(self)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class MainWindow < Qt::MainWindow
|
|
84
|
+
|
|
85
|
+
# File menu
|
|
86
|
+
slots 'on_newAction_triggered()'
|
|
87
|
+
slots 'on_openAction_triggered()'
|
|
88
|
+
slots 'on_saveAction_triggered()'
|
|
89
|
+
slots 'on_saveAsAction_triggered()'
|
|
90
|
+
slots 'on_importAction_triggered()'
|
|
91
|
+
slots 'on_closeAction_triggered()'
|
|
92
|
+
slots 'on_quitAction_triggered()'
|
|
93
|
+
# Tools menu
|
|
94
|
+
slots 'on_verifyLecturersAction_triggered()'
|
|
95
|
+
slots 'on_verifyCabinetsAction_triggered()'
|
|
96
|
+
slots 'on_showLecturerStubsAction_triggered()'
|
|
97
|
+
slots 'on_showCabinetStubsAction_triggered()'
|
|
98
|
+
slots 'on_showSubjectsStubsAction_triggered()'
|
|
99
|
+
slots 'on_verifyComputerCabinetsAction_triggered()'
|
|
100
|
+
slots 'on_verifyPreferredDaysAction_triggered()'
|
|
101
|
+
# Main
|
|
102
|
+
slots 'on_dateDateEdit_dateChanged()'
|
|
103
|
+
# Self
|
|
104
|
+
slots 'open_file()'
|
|
105
|
+
slots 'clear_recent_files()'
|
|
106
|
+
slots 'refreshTableViewModel(QVariant)'
|
|
107
|
+
# help
|
|
108
|
+
slots 'on_showManualAction_triggered()'
|
|
109
|
+
# views buttons
|
|
110
|
+
slots 'on_addCabinetPushButton_clicked()'
|
|
111
|
+
slots 'on_removeCabinetPushButton_clicked()'
|
|
112
|
+
slots 'on_addCoursePushButton_clicked()'
|
|
113
|
+
slots 'on_removeCoursePushButton_clicked()'
|
|
114
|
+
slots 'on_addGroupPushButton_clicked()'
|
|
115
|
+
slots 'on_removeGroupPushButton_clicked()'
|
|
116
|
+
slots 'on_addLecturerPushButton_clicked()'
|
|
117
|
+
slots 'on_removeLecturerPushButton_clicked()'
|
|
118
|
+
slots 'on_addSemesterPushButton_clicked()'
|
|
119
|
+
slots 'on_removeSemesterPushButton_clicked()'
|
|
120
|
+
slots 'on_addSpecialityPushButton_clicked()'
|
|
121
|
+
slots 'on_removeSpecialityPushButton_clicked()'
|
|
122
|
+
slots 'on_addSubgroupPushButton_clicked()'
|
|
123
|
+
slots 'on_removeSubgroupPushButton_clicked()'
|
|
124
|
+
slots 'on_addSubjectPushButton_clicked()'
|
|
125
|
+
slots 'on_removeSubjectPushButton_clicked()'
|
|
126
|
+
slots 'on_addSpecialitySubjectPushButton_clicked()'
|
|
127
|
+
slots 'on_removeSpecialitySubjectPushButton_clicked()'
|
|
128
|
+
#connect(@ui.addSpecialitySubjectPushButton, SLOT('clicked()'), self, SLOT('on_addSpecialitySubjectPushButton_clicked()'))
|
|
129
|
+
#connect(@ui.removeSpecialitySubjectPushButton, SLOT('clicked()'), self, SLOT('on_removeSpecialitySubjectPushButton_clicked()'))
|
|
130
|
+
|
|
131
|
+
slots 'on_tabWidget_currentChanged(int)'
|
|
132
|
+
slots 'on_dataTabWidget_currentChanged(int)'
|
|
133
|
+
|
|
134
|
+
slots 'on_findByLecturerAction_triggered()'
|
|
135
|
+
slots 'on_findBySubjectAction_triggered()'
|
|
136
|
+
slots 'on_findByCabinetAction_triggered()'
|
|
137
|
+
|
|
138
|
+
slots 'on_allAction_triggered()'
|
|
139
|
+
slots 'on_allCoincidenceAction_triggered()'
|
|
140
|
+
slots 'on_allNotAssignedAction_triggered()'
|
|
141
|
+
|
|
142
|
+
slots 'on_tarificationCheckBox_toggled(bool)'
|
|
143
|
+
|
|
144
|
+
slots 'on_debugConsoleAction_triggered()'
|
|
145
|
+
|
|
146
|
+
attr_reader :ui
|
|
147
|
+
attr_reader :study_table_models
|
|
148
|
+
|
|
149
|
+
def initialize(parent = nil)
|
|
150
|
+
super(parent)
|
|
151
|
+
@ui = Ui::MainWindow.new
|
|
152
|
+
@ui.setup_ui self
|
|
153
|
+
@ui.exportMenu.enabled = false
|
|
154
|
+
@study_table_views = [@ui.studiesTableView, @ui.studiesTableView2, @ui.studiesTableView3,
|
|
155
|
+
@ui.studiesTableView4, @ui.studiesTableView5, @ui.studiesTableView6]
|
|
156
|
+
@table_views = [[Cabinet, CabinetTableModel, @ui.cabinetsTableView], [Course, CourseTableModel, @ui.coursesTableView],
|
|
157
|
+
[Group, GroupTableModel, @ui.groupsTableView], [Lecturer, LecturerTableModel, @ui.lecturersTableView],
|
|
158
|
+
[Semester, SemesterTableModel, @ui.semestersTableView], [Speciality, SpecialityTableModel, @ui.specialitiesTableView],
|
|
159
|
+
[SpecialitySubject, SpecialitySubjectTableModel, @ui.specialitySubjectsTableView],
|
|
160
|
+
[Subgroup, SubgroupTableModel, @ui.subgroupsTableView], [Subject, SubjectTableModel, @ui.subjectsTableView]]
|
|
161
|
+
# Следующие два атрибута используются для обхода бага связанного с работой GC
|
|
162
|
+
# http://stackoverflow.com/questions/9715548/cant-display-more-than-one-table-model-inheriting-from-the-same-class-on-differ
|
|
163
|
+
@table_models = @study_table_models = []
|
|
164
|
+
@tables_views_to_hide = @study_table_views + [@ui.cabinetsTableView, @ui.coursesTableView, @ui.groupsTableView,
|
|
165
|
+
@ui.lecturersTableView, @ui.semestersTableView, @ui.specialitySubjectsTableView,
|
|
166
|
+
@ui.specialitiesTableView, @ui.subgroupsTableView, @ui.subjectsTableView, @ui.dateDateEdit,
|
|
167
|
+
@ui.dayLabel, @ui.dayLabel2, @ui.dayLabel3, @ui.dayLabel4, @ui.dayLabel5, @ui.dayLabel6,
|
|
168
|
+
@ui.subjectsListView, @ui.lecturersListView, @ui.cabinetsListView, @ui.tarificationCheckBox,
|
|
169
|
+
@ui.addCabinetPushButton, @ui.addCoursePushButton, @ui.addGroupPushButton,
|
|
170
|
+
@ui.addSubgroupPushButton, @ui.addLecturerPushButton, @ui.addSemesterPushButton,
|
|
171
|
+
@ui.addSpecialityPushButton, @ui.addSpecialitySubjectPushButton, @ui.addSubjectPushButton,
|
|
172
|
+
@ui.removeCabinetPushButton, @ui.removeCoursePushButton, @ui.removeGroupPushButton,
|
|
173
|
+
@ui.removeSubgroupPushButton, @ui.removeLecturerPushButton, @ui.removeSemesterPushButton,
|
|
174
|
+
@ui.removeSpecialityPushButton, @ui.removeSpecialitySubjectPushButton, @ui.removeSubjectPushButton]
|
|
175
|
+
@widgets_to_disable = [@ui.findMenu, @ui.exportMenu, @ui.verifyMenu, @ui.saveAsAction, @ui.expandChangesAction]
|
|
176
|
+
@tables_views_to_hide.each(&:hide)
|
|
177
|
+
@widgets_to_disable.each{ |x| x.enabled = false }
|
|
178
|
+
modeActionGroup = Qt::ActionGroup.new(self)
|
|
179
|
+
modeActionGroup.setExclusive(true)
|
|
180
|
+
modeActionGroup.addAction(@ui.weeklyViewAction)
|
|
181
|
+
modeActionGroup.addAction(@ui.dailyViewAction)
|
|
182
|
+
@temp = ->(){ "#{Dir.mktmpdir('tmis')}/temp.sqlite" }
|
|
183
|
+
connect(@ui.aboutQtAction, SIGNAL('triggered()')){ Qt::Application.aboutQt }
|
|
184
|
+
connect(@ui.aboutProgramAction, SIGNAL('triggered()')){ AboutDialog.new.exec }
|
|
185
|
+
connect(@ui.exportGeneralAction, SIGNAL('triggered()')) do
|
|
186
|
+
ExportGeneralTimetableDialog.new(Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))).exec
|
|
187
|
+
end
|
|
188
|
+
connect(@ui.exportForLecturersAction, SIGNAL('triggered()')) do
|
|
189
|
+
ExportLecturerTimetableDialog.new(Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))).exec
|
|
190
|
+
end
|
|
191
|
+
connect(@ui.exportForGroupsAction, SIGNAL('triggered()')) do
|
|
192
|
+
ExportGroupTimetableDialog.new(Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))).exec
|
|
193
|
+
end
|
|
194
|
+
connect(@ui.settingsAction, SIGNAL('triggered()')){ SettingsDialog.new.exec }
|
|
195
|
+
connect(@ui.expandChangesAction, SIGNAL('triggered()')){ ExpandChangesDialog.new(self).exec }
|
|
196
|
+
@clear_recent_action = Qt::Action.new('Очистить', self)
|
|
197
|
+
@clear_recent_action.setData Qt::Variant.new('clear')
|
|
198
|
+
connect(@clear_recent_action, SIGNAL('triggered()'), self, SLOT('clear_recent_files()'))
|
|
199
|
+
@ui.dateDateEdit.setDate(Qt::Date.fromString(Date.today.to_s, Qt::ISODate))
|
|
200
|
+
setup_dateEdit(Date.today)
|
|
201
|
+
@ui.recentMenu.clear
|
|
202
|
+
@ui.recentMenu.addActions([@clear_recent_action] + Settings[:recent, :files].split.map{ |path| create_recent_action(path) })
|
|
203
|
+
#Settings[:app, :first_run] = ''
|
|
204
|
+
Settings.set_defaults_if_first_run
|
|
205
|
+
@console = ConsoleDialog.new self
|
|
206
|
+
connect(@console, SIGNAL('dialogClosed()')){ @study_table_models.each(&:cancelColoring) }
|
|
207
|
+
$TARIFICATION_MODE = false
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def on_newAction_triggered
|
|
211
|
+
Database.instance.connect_to(@temp.())
|
|
212
|
+
create_stubs
|
|
213
|
+
Group.create(title: 'New')
|
|
214
|
+
show_tables
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def create_stubs
|
|
218
|
+
Lecturer.create(surname: Settings[:stubs, :lecturer], stub: true)
|
|
219
|
+
Cabinet.create(title: Settings[:stubs, :cabinet], stub: true)
|
|
220
|
+
Subject.create(title: Settings[:stubs, :subject], stub: true)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def on_openAction_triggered
|
|
224
|
+
if (filename = Qt::FileDialog::getOpenFileName(self, 'Open File', '', 'TMIS databases (SQLite3)(*.sqlite)'))
|
|
225
|
+
Database.instance.connect_to filename
|
|
226
|
+
update_recent filename
|
|
227
|
+
show_tables
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def on_saveAction_triggered
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def on_saveAsAction_triggered
|
|
235
|
+
if (filename = Qt::FileDialog::getSaveFileName(self, 'Save File', 'NewTimetable.sqlite', 'TMIS databases (SQLite3)(*.sqlite)'))
|
|
236
|
+
filename.force_encoding('UTF-8')
|
|
237
|
+
FileUtils.cp(Database.instance.path, filename) unless Database.instance.path == filename
|
|
238
|
+
Database.instance.connect_to filename
|
|
239
|
+
update_recent filename
|
|
240
|
+
show_tables
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def on_importAction_triggered
|
|
245
|
+
please_wait do
|
|
246
|
+
if (filename = Qt::FileDialog::getOpenFileName(self, 'Open File', '', 'Spreadsheets(*.xls *.xlsx *.ods *.csv)'))
|
|
247
|
+
if Database.instance.connected?
|
|
248
|
+
(id = ImportDialog.new(Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate)))).exec
|
|
249
|
+
else
|
|
250
|
+
(id = ImportDialog.new(Date.today)).exec
|
|
251
|
+
end
|
|
252
|
+
unless id.params.empty?
|
|
253
|
+
begin
|
|
254
|
+
sheet = SpreadsheetCreater.create filename
|
|
255
|
+
reader = TimetableReader.new(sheet, id.params[:sheet])
|
|
256
|
+
monday = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate)).monday
|
|
257
|
+
if Database.instance.connected?
|
|
258
|
+
Database.instance.transaction do Study.where(date: (monday..(monday + 6))).each(&:delete) end
|
|
259
|
+
else
|
|
260
|
+
Database.instance.connect_to(@temp.())
|
|
261
|
+
create_stubs
|
|
262
|
+
end
|
|
263
|
+
TimetableManager.new(reader, id.params[:date]).save_to_db
|
|
264
|
+
show_tables
|
|
265
|
+
rescue => e
|
|
266
|
+
show_message "При импорте произошли ошибки,\nтаблица не была импортирована.\nПроверьте структуру таблицы."
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def show_message(text)
|
|
274
|
+
box = Qt::MessageBox.new
|
|
275
|
+
box.setText text
|
|
276
|
+
box.exec
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def on_closeAction_triggered
|
|
280
|
+
@tables_views_to_hide.each(&:hide)
|
|
281
|
+
@widgets_to_disable.each{ |x| x.enabled = false }
|
|
282
|
+
Database.instance.disconnect unless $TESTING
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def on_quitAction_triggered
|
|
286
|
+
on_closeAction_triggered
|
|
287
|
+
recent = @ui.recentMenu.actions
|
|
288
|
+
Settings[:recent, :files] = recent[1..recent.size-1].map{ |a| a.data.value.to_s }.join(' ')
|
|
289
|
+
puts 'Sayonara!'
|
|
290
|
+
Qt::Application.quit
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
def on_allAction_triggered
|
|
294
|
+
begin
|
|
295
|
+
@console.browser.clear
|
|
296
|
+
@console.show
|
|
297
|
+
@console.browser.append verifyLecturers
|
|
298
|
+
@console.browser.append verifyCabinets
|
|
299
|
+
@console.browser.append showComputerCabinets
|
|
300
|
+
@console.browser.append showLecturerStubs
|
|
301
|
+
@console.browser.append showCabinetStubs
|
|
302
|
+
@console.browser.append showSubjectsStubs
|
|
303
|
+
@console.browser.append showPreferredDays
|
|
304
|
+
rescue
|
|
305
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def on_allCoincidenceAction_triggered
|
|
310
|
+
begin
|
|
311
|
+
@console.browser.clear
|
|
312
|
+
@console.show
|
|
313
|
+
@console.browser.append verifyLecturers
|
|
314
|
+
@console.browser.append verifyCabinets
|
|
315
|
+
rescue
|
|
316
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def on_allNotAssignedAction_triggered
|
|
321
|
+
begin
|
|
322
|
+
@console.browser.clear
|
|
323
|
+
@console.show
|
|
324
|
+
@console.browser.append showLecturerStubs
|
|
325
|
+
@console.browser.append showCabinetStubs
|
|
326
|
+
@console.browser.append showSubjectsStubs
|
|
327
|
+
rescue
|
|
328
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def verifyLecturers
|
|
333
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
334
|
+
dates = date.monday..date.monday + 6
|
|
335
|
+
v = Verificator.new(dates)
|
|
336
|
+
res = v.verify(:lecturer_studies).map do |k, v|
|
|
337
|
+
date = k[0]
|
|
338
|
+
lecturer = Lecturer.where(id: k[1]).first
|
|
339
|
+
number = k[2]
|
|
340
|
+
if lecturer.stub
|
|
341
|
+
nil
|
|
342
|
+
else
|
|
343
|
+
v.each do |study|
|
|
344
|
+
tst = @study_table_models[date.cwday - 1]
|
|
345
|
+
tst.setColor(study.id, Qt::red)
|
|
346
|
+
end
|
|
347
|
+
"#{date} | #{lecturer} ведёт несколько пар одновременно! Номер пары: #{number}"
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
res = res.compact.join("\n")
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def on_verifyLecturersAction_triggered
|
|
354
|
+
begin
|
|
355
|
+
@console.browser.clear
|
|
356
|
+
@console.show
|
|
357
|
+
@console.browser.append verifyLecturers
|
|
358
|
+
rescue
|
|
359
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def verifyCabinets
|
|
364
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
365
|
+
dates = date.monday..date.monday + 6
|
|
366
|
+
v = Verificator.new(dates)
|
|
367
|
+
res = v.verify(:cabinet_studies).map do |k, v|
|
|
368
|
+
date = k[0]
|
|
369
|
+
cabinet= Cabinet.where(id: k[1]).first
|
|
370
|
+
number = k[2]
|
|
371
|
+
if cabinet.stub
|
|
372
|
+
nil
|
|
373
|
+
else
|
|
374
|
+
v.each{ |study| @study_table_models[date.cwday - 1].setColorCabinet(study.id, Qt::blue) }
|
|
375
|
+
"#{date} | В #{cabinet.title} проходит несколько пар одновременно! Номер пары: #{number}"
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
res = res.compact.join("\n")
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def on_verifyCabinetsAction_triggered
|
|
382
|
+
begin
|
|
383
|
+
@console.browser.clear
|
|
384
|
+
@console.show
|
|
385
|
+
@console.browser.append verifyCabinets
|
|
386
|
+
rescue
|
|
387
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
388
|
+
end
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def showLecturerStubs
|
|
392
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
393
|
+
dates = date.monday..date.monday + 6
|
|
394
|
+
v = Verificator.new(dates)
|
|
395
|
+
res = v.verify(:lecturer_stubs).map do |date, studies|
|
|
396
|
+
studies.map do |study|
|
|
397
|
+
@study_table_models[date.cwday - 1].setColor(study.id, Qt::green)
|
|
398
|
+
"#{date} | Не назначен преподаватель! Группа: #{study.get_group.title} Номер пары: #{study.number}"
|
|
399
|
+
end.join("\n")
|
|
400
|
+
end
|
|
401
|
+
res = res.compact.join("\n")
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def on_showLecturerStubsAction_triggered
|
|
405
|
+
begin
|
|
406
|
+
@console.browser.clear
|
|
407
|
+
@console.show
|
|
408
|
+
@console.browser.append showLecturerStubs
|
|
409
|
+
rescue
|
|
410
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def showCabinetStubs
|
|
415
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
416
|
+
dates = date.monday..date.monday + 6
|
|
417
|
+
v = Verificator.new(dates)
|
|
418
|
+
res = v.verify(:cabinet_stubs).map do |date, studies|
|
|
419
|
+
studies.map do |study|
|
|
420
|
+
@study_table_models[date.cwday - 1].setColorCabinet(study.id, Qt::green)
|
|
421
|
+
"#{date} | Не назначен кабинет! Группа: #{study.get_group.title} Номер пары: #{study.number}"
|
|
422
|
+
end.join("\n")
|
|
423
|
+
end
|
|
424
|
+
res = res.compact.join("\n")
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def on_showCabinetStubsAction_triggered
|
|
428
|
+
begin
|
|
429
|
+
@console.browser.clear
|
|
430
|
+
@console.show
|
|
431
|
+
@console.browser.append showCabinetStubs
|
|
432
|
+
rescue
|
|
433
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def showSubjectsStubs
|
|
438
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
439
|
+
dates = date.monday..date.monday + 6
|
|
440
|
+
v = Verificator.new(dates)
|
|
441
|
+
res = v.verify(:subject_stubs).map do |date, studies|
|
|
442
|
+
studies.map do |study|
|
|
443
|
+
@study_table_models[date.cwday - 1].setColor(study.id, Qt::green)
|
|
444
|
+
"#{date} | Не назначен предмет! Группа: #{study.get_group.title} Номер пары: #{study.number}"
|
|
445
|
+
end.join("\n")
|
|
446
|
+
end
|
|
447
|
+
res = res.compact.join("\n")
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def on_showSubjectsStubsAction_triggered
|
|
451
|
+
begin
|
|
452
|
+
@console.browser.clear
|
|
453
|
+
@console.show
|
|
454
|
+
@console.browser.append showSubjectsStubs
|
|
455
|
+
rescue
|
|
456
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def showComputerCabinets
|
|
461
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
462
|
+
dates = date.monday..date.monday + 6
|
|
463
|
+
v = Verificator.new(dates)
|
|
464
|
+
res = v.verify(:computer_cabinets).map do |date, studies|
|
|
465
|
+
studies.map do |study|
|
|
466
|
+
@study_table_models[date.cwday - 1].setColorCabinet(study.id, Qt::yellow)
|
|
467
|
+
"#{date} | Занятие подгруппы проходит не в компьютерном кабинете! Группа: #{study.get_group.title} Номер пары: #{study.number}"
|
|
468
|
+
end.join("\n")
|
|
469
|
+
end
|
|
470
|
+
res = res.compact.join("\n")
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def on_verifyComputerCabinetsAction_triggered
|
|
474
|
+
begin
|
|
475
|
+
@console.browser.clear
|
|
476
|
+
@console.show
|
|
477
|
+
@console.browser.append showComputerCabinets
|
|
478
|
+
rescue
|
|
479
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def showPreferredDays
|
|
484
|
+
date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
485
|
+
dates = date.monday..date.monday + 6
|
|
486
|
+
v = Verificator.new(dates)
|
|
487
|
+
res = v.verify(:preferred_days).map do |date, studies|
|
|
488
|
+
studies.map do |study|
|
|
489
|
+
@study_table_models[date.cwday - 1].setColorCabinet(study.id, Qt::yellow)
|
|
490
|
+
"#{date} | #{study.lecturer.to_s} предпочитает вести занятия в другой день! Группа: #{study.get_group.title} Номер пары: #{study.number}"
|
|
491
|
+
end.join("\n")
|
|
492
|
+
end
|
|
493
|
+
res = res.compact.join("\n")
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def on_verifyPreferredDaysAction_triggered
|
|
497
|
+
begin
|
|
498
|
+
@console.browser.clear
|
|
499
|
+
@console.show
|
|
500
|
+
@console.browser.append showPreferredDays
|
|
501
|
+
rescue
|
|
502
|
+
show_message "При проверке произошли ошибки.\nПроверьте таблицы данных и расписание"
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
#def groupAndSubgroup
|
|
507
|
+
# date = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate))
|
|
508
|
+
# dates = date.monday..date.monday + 6
|
|
509
|
+
# v = Verificator.new(dates)
|
|
510
|
+
# res = v.verify(:group_and_subgroup).map do |k, v|
|
|
511
|
+
# date = k[0]
|
|
512
|
+
# lecturer = Lecturer.where(id: k[1]).first
|
|
513
|
+
# number = k[2]
|
|
514
|
+
# if lecturer.stub
|
|
515
|
+
# nil
|
|
516
|
+
# else
|
|
517
|
+
# v.each{ |study| @study_table_models[date.cwday - 1].setColor(study.id Qt::red) }
|
|
518
|
+
# "#{date} | #{lecturer} ведёт несколько пар одновременно! Номер пары: #{number}"
|
|
519
|
+
# end
|
|
520
|
+
# end
|
|
521
|
+
#end
|
|
522
|
+
#
|
|
523
|
+
#def on_verifyGroupAndSubgroup
|
|
524
|
+
# @console.browser.clear
|
|
525
|
+
# @console.show
|
|
526
|
+
# @console.browser.append groupAndSubgroup
|
|
527
|
+
#end
|
|
528
|
+
|
|
529
|
+
class EntityItemModel < Qt::AbstractItemModel
|
|
530
|
+
def initialize(lambda, parent = nil)
|
|
531
|
+
super(parent)
|
|
532
|
+
@get_entities = lambda
|
|
533
|
+
@entities = @get_entities.()
|
|
534
|
+
@size = @entities.size
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
def refresh
|
|
538
|
+
@entities = @get_entities.()
|
|
539
|
+
@size = @entities.size
|
|
540
|
+
emit layoutChanged()
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
def index(row, column, parent)
|
|
544
|
+
createIndex(row, column)
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
def parent(index)
|
|
548
|
+
Qt::ModelIndex.new()
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
def columnCount(parent = self)
|
|
552
|
+
1
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def rowCount(parent = self)
|
|
556
|
+
@size
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def data(index, role = Qt::DisplayRole, data = nil)
|
|
560
|
+
if role == Qt::DisplayRole && index.valid?
|
|
561
|
+
@entities[index.row].to_s.to_v
|
|
562
|
+
else
|
|
563
|
+
Qt::Variant.new
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def flags(index)
|
|
568
|
+
if index.valid?
|
|
569
|
+
Qt::ItemIsDragEnabled | super(index)
|
|
570
|
+
else
|
|
571
|
+
super(index)
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
def mimeData(indexes)
|
|
576
|
+
entity = @entities[indexes.first.row]
|
|
577
|
+
ba = Qt::ByteArray.new entity.id.to_s # Marshal.dump entity?
|
|
578
|
+
mime_type = "application/#{entity.class.to_s.downcase}"
|
|
579
|
+
mime_data = super indexes # для обхода ошибки сегментации Qt::MimeData создаётся с помощью родительского метода
|
|
580
|
+
mime_data.setData(mime_type, ba)
|
|
581
|
+
mime_data
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
def show_tables
|
|
586
|
+
@table_models = @table_views.map do |entity, table_model, table_view|
|
|
587
|
+
model = table_model.new(entity.all, table_view)
|
|
588
|
+
proxy_model = model
|
|
589
|
+
setup_table_view(table_view, proxy_model, Qt::HeaderView::Stretch)
|
|
590
|
+
model
|
|
591
|
+
end
|
|
592
|
+
setup_study_table_views
|
|
593
|
+
@ui.dateDateEdit.show
|
|
594
|
+
@tables_views_to_hide.each(&:show)
|
|
595
|
+
@widgets_to_disable.each{ |x| x.enabled = true }
|
|
596
|
+
#@ui.studiesTableView.setSpan(0, 0, 1, 3)
|
|
597
|
+
model = EntityItemModel.new(->(){ Subject.all }, self)
|
|
598
|
+
@ui.subjectsListView.setModel model
|
|
599
|
+
@ui.subjectsListView.show
|
|
600
|
+
model = EntityItemModel.new(->(){ Lecturer.all }, self)
|
|
601
|
+
@ui.lecturersListView.setModel model
|
|
602
|
+
@ui.lecturersListView.show
|
|
603
|
+
model = EntityItemModel.new(->(){ Cabinet.all }, self)
|
|
604
|
+
@ui.cabinetsListView.setModel model
|
|
605
|
+
@ui.cabinetsListView.show
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
def on_tarificationCheckBox_toggled(checked)
|
|
609
|
+
if checked
|
|
610
|
+
$TARIFICATION_MODE = true
|
|
611
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
612
|
+
@ui.subjectsListView.setModel model
|
|
613
|
+
@ui.subjectsListView.show
|
|
614
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
615
|
+
@ui.lecturersListView.setModel model
|
|
616
|
+
@ui.lecturersListView.show
|
|
617
|
+
else
|
|
618
|
+
$TARIFICATION_MODE = false
|
|
619
|
+
model = EntityItemModel.new(->(){ Subject.all }, self)
|
|
620
|
+
@ui.subjectsListView.setModel model
|
|
621
|
+
@ui.subjectsListView.show
|
|
622
|
+
model = EntityItemModel.new(->(){ Lecturer.all }, self)
|
|
623
|
+
@ui.lecturersListView.setModel model
|
|
624
|
+
@ui.lecturersListView.show
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
def setupListViews(index)
|
|
629
|
+
return false unless $TARIFICATION_MODE
|
|
630
|
+
string = index.model.data(index, Qt::UserRole).toString
|
|
631
|
+
if string.nil? || string.empty?
|
|
632
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
633
|
+
@ui.subjectsListView.setModel model
|
|
634
|
+
@ui.subjectsListView.show
|
|
635
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
636
|
+
@ui.lecturersListView.setModel model
|
|
637
|
+
@ui.lecturersListView.show
|
|
638
|
+
else
|
|
639
|
+
entity = Marshal.load(Base64.decode64(string))
|
|
640
|
+
p entity
|
|
641
|
+
if entity.class == Study
|
|
642
|
+
group = entity.groupable.get_group
|
|
643
|
+
course = group.course
|
|
644
|
+
if course.nil?
|
|
645
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
646
|
+
@ui.subjectsListView.setModel model
|
|
647
|
+
@ui.subjectsListView.show
|
|
648
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
649
|
+
@ui.lecturersListView.setModel model
|
|
650
|
+
@ui.lecturersListView.show
|
|
651
|
+
else
|
|
652
|
+
semester = course.current_semester
|
|
653
|
+
get_subjects = ->() do
|
|
654
|
+
if entity.lecturer && entity.subject.stub
|
|
655
|
+
SpecialitySubject.where(lecturer_id: entity.lecturer, speciality_id: group.speciality, semester_id: semester).map(&:subject)
|
|
656
|
+
else
|
|
657
|
+
SpecialitySubject.where(speciality_id: group.speciality, semester_id: semester).map(&:subject)
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
get_lecturers = ->() do
|
|
661
|
+
if entity.subject && entity.lecturer.stub
|
|
662
|
+
SpecialitySubject.where(subject_id: entity.subject, speciality_id: group.speciality, semester_id: semester).map(&:lecturer)
|
|
663
|
+
else
|
|
664
|
+
SpecialitySubject.where(speciality_id: group.speciality, semester_id: semester).map(&:lecturer)
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
model = EntityItemModel.new(get_subjects, self)
|
|
668
|
+
@ui.subjectsListView.setModel model
|
|
669
|
+
@ui.subjectsListView.show
|
|
670
|
+
model = EntityItemModel.new(get_lecturers, self)
|
|
671
|
+
@ui.lecturersListView.setModel model
|
|
672
|
+
@ui.lecturersListView.show
|
|
673
|
+
end
|
|
674
|
+
elsif entity.class == Group
|
|
675
|
+
group = entity
|
|
676
|
+
course = group.course
|
|
677
|
+
if course.nil?
|
|
678
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
679
|
+
@ui.subjectsListView.setModel model
|
|
680
|
+
@ui.subjectsListView.show
|
|
681
|
+
model = EntityItemModel.new(->(){ [] }, self)
|
|
682
|
+
@ui.lecturersListView.setModel model
|
|
683
|
+
@ui.lecturersListView.show
|
|
684
|
+
else
|
|
685
|
+
semester = course.current_semester
|
|
686
|
+
get_subjects = ->() do
|
|
687
|
+
SpecialitySubject.where(speciality_id: group.speciality, semester_id: semester).map(&:subject)
|
|
688
|
+
end
|
|
689
|
+
get_lecturers = ->() do
|
|
690
|
+
SpecialitySubject.where(speciality_id: group.speciality, semester_id: semester).map(&:lecturer)
|
|
691
|
+
end
|
|
692
|
+
model = EntityItemModel.new(get_subjects, self)
|
|
693
|
+
@ui.subjectsListView.setModel model
|
|
694
|
+
@ui.subjectsListView.show
|
|
695
|
+
model = EntityItemModel.new(get_lecturers, self)
|
|
696
|
+
@ui.lecturersListView.setModel model
|
|
697
|
+
@ui.lecturersListView.show
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
end
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
def filterListViews(study64)
|
|
704
|
+
if study.subject
|
|
705
|
+
|
|
706
|
+
end
|
|
707
|
+
if study.lecturer
|
|
708
|
+
|
|
709
|
+
end
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
def setup_study_table_views
|
|
713
|
+
@ui.deleteAction.disconnect(SIGNAL('triggered()'))
|
|
714
|
+
monday = Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate)).monday
|
|
715
|
+
@study_table_models = @study_table_views.each_with_index.map do |view, index|
|
|
716
|
+
model = setup_study_table_view(view, monday + index)
|
|
717
|
+
model.disconnect(SIGNAL('studySaved(QVariant)'))
|
|
718
|
+
view.disconnect(SIGNAL('doubleClicked(QModelIndex)'))
|
|
719
|
+
view.disconnect(SIGNAL('customContextMenuRequested(QPoint)'))
|
|
720
|
+
view.disconnect(SIGNAL('clicked(QModelIndex)'))
|
|
721
|
+
model.disconnect(SIGNAL('refreshTarification(QModelIndex)'))
|
|
722
|
+
connect(view, SIGNAL('customContextMenuRequested(QPoint)'), model, SLOT('displayMenu(QPoint)'))
|
|
723
|
+
connect(view, SIGNAL('clicked(QModelIndex)')){ |index| setupListViews(index) }
|
|
724
|
+
connect(model, SIGNAL('refreshTarification(QModelIndex)')){ |index| setupListViews(index) }
|
|
725
|
+
connect(view, SIGNAL('doubleClicked(QModelIndex)'), model, SLOT('editStudy(QModelIndex)'))
|
|
726
|
+
#connect(model, SIGNAL('studySaved(QString)')){|study64| filterListViews(study64) }
|
|
727
|
+
connect(model, SIGNAL('studySaved(QVariant)'), self, SLOT('refreshTableViewModel(QVariant)'))
|
|
728
|
+
connect(@ui.deleteAction, SIGNAL('triggered()'), model, SLOT('removeData()'))
|
|
729
|
+
connect(@ui.cancelVerifyingAction, SIGNAL('triggered()'), model, SLOT('cancelColoring()'))
|
|
730
|
+
view.setContextMenuPolicy(Qt::CustomContextMenu)
|
|
731
|
+
model
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
def refreshTableViewModel(date_variant)
|
|
736
|
+
@study_table_models[date_variant.value.dayOfWeek - 1].refresh
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
def setup_study_table_view(view, date)
|
|
740
|
+
model = StudyTableModel.new(date, view)
|
|
741
|
+
view = setup_table_view2(view, model, Qt::HeaderView::Interactive)
|
|
742
|
+
model.columnCount.times{ |i| i.odd? ? view.setColumnWidth(i, 50) : view.setColumnWidth(i, 150) }
|
|
743
|
+
model.rowCount.times{ |i| view.setRowHeight(i, 50) }
|
|
744
|
+
model
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
def setup_table_view2(table_view, table_model, resize_mode)
|
|
748
|
+
table_view.setModel(table_model)
|
|
749
|
+
table_view.horizontalHeader.setResizeMode(resize_mode)
|
|
750
|
+
table_view.verticalHeader.setResizeMode(resize_mode)
|
|
751
|
+
table_view.show
|
|
752
|
+
table_view
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
##Contract IsA[Qt::TableView], IsA[Qt::AbstractTableModel], IsA[Qt::Enum] => IsA[Qt::TableView]
|
|
756
|
+
def setup_table_view(table_view, table_model, resize_mode)
|
|
757
|
+
table_view.setModel(table_model)
|
|
758
|
+
table_view.horizontalHeader.setResizeMode(resize_mode)
|
|
759
|
+
table_view.verticalHeader.setResizeMode(Qt::HeaderView::ResizeToContents)
|
|
760
|
+
table_view.show
|
|
761
|
+
table_view
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
def open_file
|
|
765
|
+
filename = sender.data.value.to_s
|
|
766
|
+
if File.exist? filename
|
|
767
|
+
Database.instance.connect_to filename
|
|
768
|
+
update_recent filename
|
|
769
|
+
show_tables
|
|
770
|
+
end
|
|
771
|
+
end
|
|
772
|
+
|
|
773
|
+
#Contract String => Qt::Action
|
|
774
|
+
def create_recent_action(path)
|
|
775
|
+
action = Qt::Action.new(path[path.size-10..path.size], self)
|
|
776
|
+
connect(action, SIGNAL('triggered()'), self, SLOT('open_file()'))
|
|
777
|
+
action.setData Qt::Variant.new(path); action
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
#Contract String => Any
|
|
781
|
+
def update_recent(filename)
|
|
782
|
+
actions = @ui.recentMenu.actions
|
|
783
|
+
if actions.size > 5
|
|
784
|
+
@ui.recentMenu.clear
|
|
785
|
+
@ui.recentMenu.addActions([@clear_recent_action] + actions[1..actions.size-1])
|
|
786
|
+
else
|
|
787
|
+
@ui.recentMenu.addAction create_recent_action(filename)
|
|
788
|
+
end
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
def clear_recent_files
|
|
792
|
+
@ui.recentMenu.clear
|
|
793
|
+
@ui.recentMenu.addAction @clear_recent_action
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
def on_dateDateEdit_dateChanged
|
|
797
|
+
setup_dateEdit(Date.parse(@ui.dateDateEdit.date.toString(Qt::ISODate)))
|
|
798
|
+
setup_study_table_views if Database.instance.connected?
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
def setup_dateEdit(date)
|
|
802
|
+
type = date.cweek.even? ? "Чётная" : "Нечётная"
|
|
803
|
+
@ui.dateDateEdit.displayFormat = "Неделя №#{date.cweek} (#{type}) dddd - d MMMM yy"
|
|
804
|
+
end
|
|
805
|
+
|
|
806
|
+
def please_wait(&block)
|
|
807
|
+
@ui.statusbar.showMessage 'Please, wait...'
|
|
808
|
+
yield block
|
|
809
|
+
@ui.statusbar.clearMessage
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
def on_showManualAction_triggered
|
|
813
|
+
# binding doesn't include QHelpEngine
|
|
814
|
+
#helpEngine Qt::HelpEngineCore('test.qhc')
|
|
815
|
+
#links = helpEngine.linksForIdentifier('MyDialog::ChangeButton')
|
|
816
|
+
#if links.count
|
|
817
|
+
# helpData = helpEngine.fileData links.constBegin.value
|
|
818
|
+
# if !helpData.isEmpty
|
|
819
|
+
# displayHelp helpData
|
|
820
|
+
# end
|
|
821
|
+
#end
|
|
822
|
+
Qt::DesktopServices::openUrl(Qt::Url.new('https://github.com/Noein/TMIS/wiki'))
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
def on_addCabinetPushButton_clicked
|
|
826
|
+
@ui.cabinetsTableView.model.insert_new
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
def on_removeCabinetPushButton_clicked
|
|
830
|
+
@ui.cabinetsTableView.model.remove_current
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
def on_addCoursePushButton_clicked
|
|
834
|
+
@ui.coursesTableView.model.insert_new
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
def on_removeCoursePushButton_clicked
|
|
838
|
+
@ui.coursesTableView.model.remove_current
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
def on_addGroupPushButton_clicked
|
|
842
|
+
@ui.groupsTableView.model.insert_new
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
def on_removeGroupPushButton_clicked
|
|
846
|
+
@ui.groupsTableView.model.remove_current
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
def on_addLecturerPushButton_clicked
|
|
850
|
+
@ui.lecturersTableView.model.insert_new
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
def on_removeLecturerPushButton_clicked
|
|
854
|
+
@ui.lecturersTableView.model.remove_current
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
def on_addSemesterPushButton_clicked
|
|
858
|
+
@ui.semestersTableView.model.insert_new
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
def on_removeSemesterPushButton_clicked
|
|
862
|
+
@ui.semestersTableView.model.remove_current
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
def on_addSpecialitySubjectPushButton_clicked
|
|
866
|
+
@ui.specialitySubjectsTableView.model.insert_new
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
def on_removeSpecialitySubjectPushButton_clicked
|
|
870
|
+
@ui.specialitySubjectsTableView.model.remove_current
|
|
871
|
+
end
|
|
872
|
+
|
|
873
|
+
def on_addSpecialityPushButton_clicked
|
|
874
|
+
@ui.specialitiesTableView.model.insert_new
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
def on_removeSpecialityPushButton_clicked
|
|
878
|
+
@ui.specialitiesTableView.model.remove_current
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
def on_addSubgroupPushButton_clicked
|
|
882
|
+
@ui.subgroupsTableView.model.insert_new
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
def on_removeSubgroupPushButton_clicked
|
|
886
|
+
@ui.subgroupsTableView.model.remove_current
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
def on_addSubjectPushButton_clicked
|
|
890
|
+
@ui.subjectsTableView.model.insert_new
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
def on_removeSubjectPushButton_clicked
|
|
894
|
+
@ui.subjectsTableView.model.remove_current
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
def on_dataTabWidget_currentChanged(index)
|
|
898
|
+
if Database.instance.connected?
|
|
899
|
+
@table_views.each do |c, m, view|
|
|
900
|
+
model = view.model
|
|
901
|
+
model.refresh
|
|
902
|
+
proxy_model = model
|
|
903
|
+
view.model = proxy_model
|
|
904
|
+
end
|
|
905
|
+
end
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
def on_tabWidget_currentChanged(index)
|
|
909
|
+
if Database.instance.connected?
|
|
910
|
+
if index == 0
|
|
911
|
+
@study_table_models.each(&:refresh)
|
|
912
|
+
[@ui.subjectsListView, @ui.lecturersListView, @ui.cabinetsListView].each{|view| view.model.refresh }
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
|
|
917
|
+
def on_findByLecturerAction_triggered
|
|
918
|
+
FindDialog.new(:lecturer, self).show
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
def on_findBySubjectAction_triggered
|
|
922
|
+
FindDialog.new(:subject, self).show
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
def on_findByCabinetAction_triggered
|
|
926
|
+
FindDialog.new(:cabinet, self).show
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
def on_debugConsoleAction_triggered
|
|
930
|
+
DebugConsoleDialog.new(self).show
|
|
931
|
+
end
|
|
932
|
+
|
|
933
|
+
end
|