Back to index

fet  5.18.0
timetableviewteachersform.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           timetableviewteachersform.cpp  -  description
00003                              -------------------
00004     begin                : Wed May 14 2003
00005     copyright            : (C) 2003 by Lalescu Liviu
00006     email                : Please see http://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "tablewidgetupdatebug.h"
00019 
00020 #include "longtextmessagebox.h"
00021 
00022 #include "fetmainform.h"
00023 #include "timetableviewteachersform.h"
00024 #include "timetable_defs.h"
00025 #include "timetable.h"
00026 #include "solution.h"
00027 
00028 #include "fet.h"
00029 
00030 #include "matrix.h"
00031 
00032 #include "lockunlock.h"
00033 
00034 #include <QMessageBox>
00035 
00036 #include <QTableWidget>
00037 #include <QTableWidgetItem>
00038 #include <QHeaderView>
00039 
00040 #include <QAbstractItemView>
00041 
00042 #include <QListWidget>
00043 
00044 #include <QList>
00045 #include <QSplitter>
00046 
00047 #include <QCoreApplication>
00048 #include <QApplication>
00049 
00050 #include <QString>
00051 #include <QStringList>
00052 
00053 #include <QSplitter>
00054 #include <QSettings>
00055 #include <QObject>
00056 #include <QMetaObject>
00057 
00058 extern const QString COMPANY;
00059 extern const QString PROGRAM;
00060 
00061 extern bool students_schedule_ready;
00062 extern bool teachers_schedule_ready;
00063 
00064 extern Solution best_solution;
00065 
00066 extern bool simulation_running;
00067 
00068 extern Matrix3D<bool> teacherNotAvailableDayHour;
00069 extern Matrix2D<bool> breakDayHour;
00070 
00071 extern QSet <int> idsOfLockedTime;        //care about locked activities in view forms
00072 extern QSet <int> idsOfLockedSpace;              //care about locked activities in view forms
00073 extern QSet <int> idsOfPermanentlyLockedTime;    //care about locked activities in view forms
00074 extern QSet <int> idsOfPermanentlyLockedSpace;   //care about locked activities in view forms
00075 
00076 extern CommunicationSpinBox communicationSpinBox;       //small hint to sync the forms
00077 
00078 TimetableViewTeachersForm::TimetableViewTeachersForm(QWidget* parent): QDialog(parent)
00079 {
00080        setupUi(this);
00081        
00082        closePushButton->setDefault(true);
00083        
00084        detailsTextEdit->setReadOnly(true);
00085 
00086        //columnResizeModeInitialized=false;
00087 
00088        QList<int> tmpList;
00089        tmpList<<5000<<5000;
00090        verticalSplitter->setSizes(tmpList);
00091 
00092        QList<int> tmpList2;
00093        tmpList2<<3000<<10000;
00094        horizontalSplitter->setSizes(tmpList2);
00095 
00096        teachersTimetableTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
00097        
00098        teachersListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00099 
00100        connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
00101        connect(teachersListWidget, SIGNAL(currentTextChanged(const QString&)), this, SLOT(teacherChanged(const QString&)));
00102        connect(teachersTimetableTable, SIGNAL(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)), this, SLOT(currentItemChanged(QTableWidgetItem*, QTableWidgetItem*)));
00103        connect(lockTimePushButton, SIGNAL(clicked()), this, SLOT(lockTime()));
00104        connect(lockSpacePushButton, SIGNAL(clicked()), this, SLOT(lockSpace()));
00105        connect(lockTimeSpacePushButton, SIGNAL(clicked()), this, SLOT(lockTimeSpace()));
00106 
00107        connect(helpPushButton, SIGNAL(clicked()), this, SLOT(help()));
00108 
00109        centerWidgetOnScreen(this);
00110        restoreFETDialogGeometry(this);
00111 
00112        //restore vertical splitter state
00113        QSettings settings(COMPANY, PROGRAM);
00114        if(settings.contains(this->metaObject()->className()+QString("/vertical-splitter-state")))
00115               verticalSplitter->restoreState(settings.value(this->metaObject()->className()+QString("/vertical-splitter-state")).toByteArray());
00116 
00117        //restore horizontal splitter state
00118        //QSettings settings(COMPANY, PROGRAM);
00119        if(settings.contains(this->metaObject()->className()+QString("/horizontal-splitter-state")))
00120               horizontalSplitter->restoreState(settings.value(this->metaObject()->className()+QString("/horizontal-splitter-state")).toByteArray());
00121 
00123        QSet<int> backupLockedTime;
00124        QSet<int> backupPermanentlyLockedTime;
00125        QSet<int> backupLockedSpace;
00126        QSet<int> backupPermanentlyLockedSpace;
00127        
00128        backupLockedTime=idsOfLockedTime;
00129        backupPermanentlyLockedTime=idsOfPermanentlyLockedTime;
00130        backupLockedSpace=idsOfLockedSpace;
00131        backupPermanentlyLockedSpace=idsOfPermanentlyLockedSpace;
00132        
00133        //added by Volker Dirr
00134        //these 2 lines are not really needed - just to be safer
00135        LockUnlock::computeLockedUnlockedActivitiesTimeSpace();
00136        
00137        assert(backupLockedTime==idsOfLockedTime);
00138        assert(backupPermanentlyLockedTime==idsOfPermanentlyLockedTime);
00139        assert(backupLockedSpace==idsOfLockedSpace);
00140        assert(backupPermanentlyLockedSpace==idsOfPermanentlyLockedSpace);
00142 
00143        LockUnlock::increaseCommunicationSpinBox();
00144        
00145        teachersTimetableTable->setRowCount(gt.rules.nHoursPerDay);
00146        teachersTimetableTable->setColumnCount(gt.rules.nDaysPerWeek);
00147        for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00148               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.daysOfTheWeek[j]);
00149               teachersTimetableTable->setHorizontalHeaderItem(j, item);
00150        }
00151        for(int i=0; i<gt.rules.nHoursPerDay; i++){
00152               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.hoursOfTheDay[i]);
00153               teachersTimetableTable->setVerticalHeaderItem(i, item);
00154        }
00155 
00156        for(int j=0; j<gt.rules.nHoursPerDay; j++){
00157               for(int k=0; k<gt.rules.nDaysPerWeek; k++){
00158                      QTableWidgetItem* item= new QTableWidgetItem();
00159                      item->setTextAlignment(Qt::AlignCenter);
00160                      item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
00161 
00162                      teachersTimetableTable->setItem(j, k, item);
00163                      
00164                      //if(j==0 && k==0)
00165                             //teachersTimetableTable->setCurrentItem(item);
00166               }
00167        }
00168        
00169        //resize columns
00170        //if(!columnResizeModeInitialized){
00171        teachersTimetableTable->horizontalHeader()->setMinimumSectionSize(teachersTimetableTable->horizontalHeader()->defaultSectionSize());
00172        //     columnResizeModeInitialized=true;
00173        teachersTimetableTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
00174        //}
00176        
00177        teachersListWidget->clear();
00178 
00179        if(gt.rules.nInternalTeachers!=gt.rules.teachersList.count()){
00180               QMessageBox::warning(this, tr("FET warning"), tr("Cannot display the timetable, because you added or removed some teachers. Please regenerate the timetable and then view it"));
00181        }
00182        else{
00183               for(int i=0; i<gt.rules.nInternalTeachers; i++)
00184                      teachersListWidget->addItem(gt.rules.internalTeachersList[i]->name);
00185        }
00186 
00187        if(teachersListWidget->count()>0)
00188               teachersListWidget->setCurrentRow(0);
00189 
00190        //added by Volker Dirr
00191        connect(&communicationSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateTeachersTimetableTable()));
00192 }
00193 
00194 TimetableViewTeachersForm::~TimetableViewTeachersForm()
00195 {
00196        saveFETDialogGeometry(this);
00197 
00198        //save vertical splitter state
00199        QSettings settings(COMPANY, PROGRAM);
00200        settings.setValue(this->metaObject()->className()+QString("/vertical-splitter-state"), verticalSplitter->saveState());
00201 
00202        //save horizontal splitter state
00203        //QSettings settings(COMPANY, PROGRAM);
00204        settings.setValue(this->metaObject()->className()+QString("/horizontal-splitter-state"), horizontalSplitter->saveState());
00205 }
00206 
00207 void TimetableViewTeachersForm::resizeRowsAfterShow()
00208 {
00209        teachersTimetableTable->resizeRowsToContents();
00210 //     tableWidgetUpdateBug(teachersTimetableTable);
00211 }
00212 
00213 void TimetableViewTeachersForm::teacherChanged(const QString &teacherName)
00214 {
00215        if(!(students_schedule_ready && teachers_schedule_ready)){
00216               QMessageBox::warning(this, tr("FET warning"), tr("Timetable not available in view teachers timetable dialog - please generate a new timetable"));
00217               return;
00218        }
00219        assert(students_schedule_ready && teachers_schedule_ready);
00220 
00221        if(teacherName==QString())
00222               return;
00223 
00224        int teacherId=gt.rules.searchTeacher(teacherName);
00225        if(teacherId<0){
00226               QMessageBox::warning(this, tr("FET warning"), tr("Invalid teacher - please close this dialog and open a new view teachers dialog"));
00227               return;
00228        }
00229 
00230        updateTeachersTimetableTable();
00231 }
00232 
00233 void TimetableViewTeachersForm::updateTeachersTimetableTable(){
00234        if(!(students_schedule_ready && teachers_schedule_ready)){
00235               QMessageBox::warning(this, tr("FET warning"), tr("Timetable not available in view teachers timetable dialog - please generate a new timetable "
00236               "or close the timetable view teachers dialog"));
00237               return;
00238        }
00239        assert(students_schedule_ready && teachers_schedule_ready);
00240 
00241        if(gt.rules.nInternalRooms!=gt.rules.roomsList.count()){
00242               QMessageBox::warning(this, tr("FET warning"), tr("Cannot display the timetable, because you added or removed some rooms. Please regenerate the timetable and then view it"));
00243               return;
00244        }
00245 
00246        QString s;
00247        QString teachername;
00248 
00249        if(teachersListWidget->currentRow()<0 || teachersListWidget->currentRow()>=teachersListWidget->count())
00250               return;
00251 
00252        teachername = teachersListWidget->currentItem()->text();
00253        
00254        if(gt.rules.searchTeacher(teachername)<0){
00255               QMessageBox::warning(this, tr("FET warning"), tr("You have an old timetable view teachers dialog opened - please close it"));
00256               return;
00257        }
00258 
00259        s = teachername;
00260        teacherNameTextLabel->setText(s);
00261 
00262        assert(gt.rules.initialized);
00263 /*     teachersTimetableTable->setNumRows(gt.rules.nHoursPerDay);
00264        teachersTimetableTable->setNumCols(gt.rules.nDaysPerWeek);
00265        for(int j=0; j<gt.rules.nDaysPerWeek; j++)
00266               teachersTimetableTable->horizontalHeader()->setLabel(j, gt.rules.daysOfTheWeek[j]);
00267        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00268               teachersTimetableTable->verticalHeader()->setLabel(i, gt.rules.hoursOfTheDay[i]);*/
00269 
00270        int teacher=gt.rules.searchTeacher(teachername);
00271        if(teacher<0){
00272               QMessageBox::warning(this, tr("FET information"),
00273                      tr("The teacher's timetable cannot be printed, because the teacher is invalid"));
00274               return;
00275        }
00276 
00277        for(int j=0; j<gt.rules.nHoursPerDay && j<teachersTimetableTable->rowCount(); j++){
00278               for(int k=0; k<gt.rules.nDaysPerWeek && k<teachersTimetableTable->columnCount(); k++){
00279                      s = "";
00280                      int ai=teachers_timetable_weekly[teacher][k][j]; //activity index
00281                      //Activity* act=gt.rules.activitiesList.at(ai);
00282                      if(ai!=UNALLOCATED_ACTIVITY){
00283                             Activity* act=&gt.rules.internalActivitiesList[ai];
00284                             assert(act!=NULL);
00285                             
00286                             QString ats=act->activityTagsNames.join(", ");
00287                             s += act->subjectName+" "+ats;
00288                             
00289                             //students
00290                             if(act->studentsNames.count()>0){
00291                                    s+="\n";
00292                                    s+=act->studentsNames.join(", ");
00293                             }
00294 
00295                             int r=best_solution.rooms[ai];
00296                             if(r!=UNALLOCATED_SPACE && r!=UNSPECIFIED_ROOM){
00297                                    //s+=" ";
00298                                    //s+=tr("R:%1", "Room").arg(gt.rules.internalRoomsList[r]->name);
00299                                    s+="\n";
00300                                    s+=gt.rules.internalRoomsList[r]->name;
00301                             }
00302                             
00303                             //added by Volker Dirr (start)
00304                             QString descr="";
00305                             QString t="";
00306                             if(idsOfPermanentlyLockedTime.contains(act->id)){
00307                                    descr+=QCoreApplication::translate("TimetableViewForm", "PLT", "Abbreviation for permanently locked time. There are 4 string: permanently locked time, permanently locked space, "
00308                                           "locked time, locked space. Make sure their abbreviations contain different letters and are visually different, so user can easily differentiate between them."
00309                                           " These abbreviations may appear also in other places, please use the same abbreviations.");
00310                                    t=", ";
00311                             }
00312                             else if(idsOfLockedTime.contains(act->id)){
00313                                    descr+=QCoreApplication::translate("TimetableViewForm", "LT", "Abbreviation for locked time. There are 4 string: permanently locked time, permanently locked space, "
00314                                           "locked time, locked space. Make sure their abbreviations contain different letters and are visually different, so user can easily differentiate between them."
00315                                           " These abbreviations may appear also in other places, please use the same abbreviations.");
00316                                    t=", ";
00317                             }
00318                             if(idsOfPermanentlyLockedSpace.contains(act->id)){
00319                                    descr+=t+QCoreApplication::translate("TimetableViewForm", "PLS", "Abbreviation for permanently locked space. There are 4 string: permanently locked time, permanently locked space, "
00320                                           "locked time, locked space. Make sure their abbreviations contain different letters and are visually different, so user can easily differentiate between them."
00321                                           " These abbreviations may appear also in other places, please use the same abbreviations.");
00322                             }
00323                             else if(idsOfLockedSpace.contains(act->id)){
00324                                    descr+=t+QCoreApplication::translate("TimetableViewForm", "LS", "Abbreviation for locked space. There are 4 string: permanently locked time, permanently locked space, "
00325                                           "locked time, locked space. Make sure their abbreviations contain different letters and are visually different, so user can easily differentiate between them."
00326                                           " These abbreviations may appear also in other places, please use the same abbreviations.");
00327                             }
00328                             if(descr!=""){
00329                                    descr.prepend("\n(");
00330                                    descr.append(")");
00331                             }
00332                             s+=descr;
00333                             //added by Volker Dirr (end)
00334                      }
00335                      else{
00336                             if(teacherNotAvailableDayHour[teacher][k][j] && PRINT_NOT_AVAILABLE_TIME_SLOTS)
00337                                    s+="-x-";
00338                             else if(breakDayHour[k][j] && PRINT_BREAK_TIME_SLOTS)
00339                                    s+="-X-";
00340                      }
00341                      teachersTimetableTable->item(j, k)->setText(s);
00342               }
00343        }
00344        //     for(int i=0; i<gt.rules.nHoursPerDay; i++) //added in version 3_9_16, on 16 Oct. 2004
00345        //            teachersTimetableTable->adjustRow(i);
00346 
00347        teachersTimetableTable->resizeRowsToContents();
00348        
00349        tableWidgetUpdateBug(teachersTimetableTable);
00350        
00351        detailActivity(teachersTimetableTable->currentItem());
00352 }
00353 
00354 void TimetableViewTeachersForm::resizeEvent(QResizeEvent* event)
00355 {
00356        QDialog::resizeEvent(event);
00357 
00358        teachersTimetableTable->resizeRowsToContents();
00359 }
00360 
00361 void TimetableViewTeachersForm::currentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
00362 {
00363        Q_UNUSED(previous);
00364        
00365        detailActivity(current);
00366 }
00367 
00368 void TimetableViewTeachersForm::detailActivity(QTableWidgetItem* item){
00369        if(item==NULL){
00370               detailsTextEdit->setPlainText(QString(""));
00371               return;
00372        }
00373 
00374        if(item->row()>=gt.rules.nHoursPerDay || item->column()>=gt.rules.nDaysPerWeek){
00375               QMessageBox::warning(this, tr("FET warning"), tr("Timetable not available in view teachers timetable dialog - please generate a new timetable "
00376               "or close the timetable view teachers dialog"));
00377               return;
00378        }
00379 
00380        if(!(students_schedule_ready && teachers_schedule_ready)){
00381               QMessageBox::warning(this, tr("FET warning"), tr("Timetable not available in view teachers timetable dialog - please generate a new timetable"));
00382               return;
00383        }
00384        assert(students_schedule_ready && teachers_schedule_ready);
00385 
00386        if(gt.rules.nInternalRooms!=gt.rules.roomsList.count()){
00387               QMessageBox::warning(this, tr("FET warning"), tr("Cannot display the timetable, because you added or removed some rooms. Please regenerate the timetable and then view it"));
00388               return;
00389        }
00390 
00391        QString s;
00392        QString teachername;
00393 
00394        if(teachersListWidget->currentRow()<0 || teachersListWidget->currentRow()>=teachersListWidget->count())
00395               return;
00396 
00397        teachername = teachersListWidget->currentItem()->text();
00398 
00399        s = teachername;
00400 
00401        teacherNameTextLabel->setText(s);
00402 
00403        int teacher=gt.rules.searchTeacher(teachername);
00404        if(teacher<0){
00405               QMessageBox::warning(this, tr("FET warning"), tr("The teacher is invalid - please close this dialog and open a new view teachers timetable"));
00406               return;
00407        }
00408        else{
00409               int j=item->row();
00410               int k=item->column();
00411               s = "";
00412               if(j>=0 && k>=0){
00413                      int ai=teachers_timetable_weekly[teacher][k][j]; //activity index
00414                      //Activity* act=gt.rules.activitiesList.at(ai);
00415                      if(ai!=UNALLOCATED_ACTIVITY){
00416                             Activity* act=&gt.rules.internalActivitiesList[ai];
00417                             assert(act!=NULL);
00418                             //s += act->getDetailedDescriptionWithConstraints(gt.rules);
00419                             s += act->getDetailedDescription(gt.rules);
00420 
00421                             //int r=rooms_timetable_weekly[teacher][k][j];
00422                             int r=best_solution.rooms[ai];
00423                             if(r!=UNALLOCATED_SPACE && r!=UNSPECIFIED_ROOM){
00424                                    s+="\n";
00425                                    s+=tr("Room: %1").arg(gt.rules.internalRoomsList[r]->name);
00426                             }
00427                             //added by Volker Dirr (start)
00428                             QString descr="";
00429                             QString t="";
00430                             if(idsOfPermanentlyLockedTime.contains(act->id)){
00431                                    descr+=QCoreApplication::translate("TimetableViewForm", "permanently locked time", "refers to activity");
00432                                    t=", ";
00433                             }
00434                             else if(idsOfLockedTime.contains(act->id)){
00435                                    descr+=QCoreApplication::translate("TimetableViewForm", "locked time", "refers to activity");
00436                                    t=", ";
00437                             }
00438                             if(idsOfPermanentlyLockedSpace.contains(act->id)){
00439                                    descr+=t+QCoreApplication::translate("TimetableViewForm", "permanently locked space", "refers to activity");
00440                             }
00441                             else if(idsOfLockedSpace.contains(act->id)){
00442                                    descr+=t+QCoreApplication::translate("TimetableViewForm", "locked space", "refers to activity");
00443                             }
00444                             if(descr!=""){
00445                                    descr.prepend("\n(");
00446                                    descr.append(")");
00447                             }
00448                             s+=descr;
00449                             //added by Volker Dirr (end)
00450                      }
00451                      else{
00452                             if(teacherNotAvailableDayHour[teacher][k][j]){
00453                                    s+=tr("Teacher is not available 100% in this slot");
00454                                    s+="\n";
00455                             }
00456                             if(breakDayHour[k][j]){
00457                                    s+=tr("Break with weight 100% in this slot");
00458                                    s+="\n";
00459                             }
00460                      }
00461               }
00462               detailsTextEdit->setPlainText(s);
00463        }
00464 }
00465 
00466 void TimetableViewTeachersForm::lockTime()
00467 {
00468        this->lock(true, false);
00469 }
00470        
00471 void TimetableViewTeachersForm::lockSpace()
00472 {
00473        this->lock(false, true);
00474 }
00475 
00476 void TimetableViewTeachersForm::lockTimeSpace()
00477 {
00478        this->lock(true, true);
00479 }
00480                      
00481 void TimetableViewTeachersForm::lock(bool lockTime, bool lockSpace)
00482 {
00483        //cout<<"teachers begin, isc="<<gt.rules.internalStructureComputed<<endl;
00484 
00485        if(simulation_running){
00486               QMessageBox::information(this, tr("FET information"),
00487                      tr("Allocation in course.\nPlease stop simulation before this."));
00488               return;
00489        }
00490 
00491        if(!(students_schedule_ready && teachers_schedule_ready)){
00492               QMessageBox::warning(this, tr("FET warning"), tr("Timetable not available in view teachers timetable dialog - please generate a new timetable"));
00493               return;
00494        }
00495        assert(students_schedule_ready && teachers_schedule_ready);
00496 
00497        if(gt.rules.nInternalRooms!=gt.rules.roomsList.count()){
00498               QMessageBox::warning(this, tr("FET warning"), tr("Cannot display the timetable, because you added or removed some rooms. Please regenerate the timetable and then view it"));
00499               return;
00500        }
00501 
00502        //find teacher index
00503        QString teachername;
00504 
00505        if(teachersListWidget->currentRow()<0 || teachersListWidget->currentRow()>=teachersListWidget->count()){
00506               QMessageBox::information(this, tr("FET information"), tr("Please select a teacher"));
00507               return;
00508        }
00509 
00510        teachername = teachersListWidget->currentItem()->text();
00511        int i=gt.rules.searchTeacher(teachername);
00512        
00513        if(i<0){
00514               QMessageBox::warning(this, tr("FET warning"), tr("Invalid teacher - please close this dialog and open a new view teachers dialog"));
00515               return;
00516        }
00517 
00518        Solution* tc=&best_solution;
00519        
00520        bool report=false; //the messages are annoying
00521        
00522        int addedT=0, unlockedT=0;
00523        int addedS=0, unlockedS=0;
00524 
00525        //lock selected activities
00526        QSet <int> careAboutIndex;         //added by Volker Dirr. Needed, because of activities with duration > 1
00527        careAboutIndex.clear();
00528        for(int j=0; j<gt.rules.nHoursPerDay && j<teachersTimetableTable->rowCount(); j++){
00529               for(int k=0; k<gt.rules.nDaysPerWeek && k<teachersTimetableTable->columnCount(); k++){
00530                      if(teachersTimetableTable->item(j, k)->isSelected()){
00531                             int ai=teachers_timetable_weekly[i][k][j];
00532                             if(ai!=UNALLOCATED_ACTIVITY && !careAboutIndex.contains(ai)){  //modified, because of activities with duration > 1
00533                                    careAboutIndex.insert(ai);                              //Needed, because of activities with duration > 1
00534                                    int a_tim=tc->times[ai];
00535                                    int hour=a_tim/gt.rules.nDaysPerWeek;
00536                                    int day=a_tim%gt.rules.nDaysPerWeek;
00537                                    //Activity* act=gt.rules.activitiesList.at(ai);
00538                                    Activity* act=&gt.rules.internalActivitiesList[ai];
00539 
00540                                    if(lockTime){
00541                                           ConstraintActivityPreferredStartingTime* ctr=new ConstraintActivityPreferredStartingTime(100.0, act->id, day, hour, false);
00542                                           bool t=gt.rules.addTimeConstraint(ctr);
00543                                           QString s;
00544                                           if(t){ //modified by Volker Dirr, so you can also unlock (start)
00545                                                  addedT++;
00546                                                  idsOfLockedTime.insert(act->id);
00547                                                  s+=tr("Added the following constraint:")+"\n"+ctr->getDetailedDescription(gt.rules);
00548                                           }
00549                                           else{
00550                                                  delete ctr;
00551                                           
00552                                                  QList<TimeConstraint*> tmptc;
00553                                                  tmptc.clear();
00554                                                  int count=0;
00555                                                  foreach(TimeConstraint* tc, gt.rules.timeConstraintsList){
00556                                                         if(tc->type==CONSTRAINT_ACTIVITY_PREFERRED_STARTING_TIME){
00557                                                                ConstraintActivityPreferredStartingTime* c=(ConstraintActivityPreferredStartingTime*) tc;
00558                                                                if(c->activityId==act->id && c->weightPercentage==100.0 && c->active && c->day>=0 && c->hour>=0){
00559                                                                       count++;
00560                                                                       if(c->permanentlyLocked){
00561                                                                              if(idsOfLockedTime.contains(c->activityId) || !idsOfPermanentlyLockedTime.contains(c->activityId)){
00562                                                                                     QMessageBox::warning(this, tr("FET warning"), tr("Small problem detected")
00563                                                                                      +"\n\n"+tr("A possible problem might be that you have 2 or more constraints of type activity preferred starting time with weight 100% related to activity id %1, please leave only one of them").arg(act->id)
00564                                                                                      +"\n\n"+tr("A possible problem might be synchronization - so maybe try to close the timetable view dialog and open it again")
00565                                                                                      +"\n\n"+tr("Please report possible bug")
00566                                                                                      );
00567                                                                              }
00568                                                                              else{
00569                                                                                     s+=tr("Constraint %1 will not be removed, because it is permanently locked. If you want to unlock it you must go to the constraints menu.").arg("\n"+c->getDetailedDescription(gt.rules)+"\n");
00570                                                                              }
00571                                                                       }
00572                                                                       else{
00573                                                                              if(!idsOfLockedTime.contains(c->activityId) || idsOfPermanentlyLockedTime.contains(c->activityId)){
00574                                                                                     QMessageBox::warning(this, tr("FET warning"), tr("Small problem detected")
00575                                                                                      +"\n\n"+tr("A possible problem might be that you have 2 or more constraints of type activity preferred starting time with weight 100% related to activity id %1, please leave only one of them").arg(act->id)
00576                                                                                      +"\n\n"+tr("A possible problem might be synchronization - so maybe try to close the timetable view dialog and open it again")
00577                                                                                      +"\n\n"+tr("Please report possible bug")
00578                                                                                      );
00579                                                                              }
00580                                                                              else{
00581                                                                                     tmptc.append(tc);
00582                                                                              }
00583                                                                       }
00584                                                                }
00585                                                         }
00586                                                  }
00587                                                  if(count!=1)
00588                                                         QMessageBox::warning(this, tr("FET warning"), tr("You may have a problem, because FET expected to delete 1 constraint, but will delete %1 constraints").arg(tmptc.size()));
00589 
00590                                                  foreach(TimeConstraint* deltc, tmptc){
00591                                                         s+=tr("The following constraint will be deleted:")+"\n"+deltc->getDetailedDescription(gt.rules)+"\n";
00592                                                         gt.rules.removeTimeConstraint(deltc);
00593                                                         idsOfLockedTime.remove(act->id);
00594                                                         unlockedT++;
00595                                                         //delete deltc; - done by rules.removeTim...
00596                                                  }
00597                                                  tmptc.clear();
00598                                                  //gt.rules.internalStructureComputed=false;
00599                                           }  //modified by Volker Dirr, so you can also unlock (end)
00600                                           
00601                                           if(report){
00602                                                  int k;
00603                                                  if(t)
00604                                                         k=QMessageBox::information(this, tr("FET information"), s,
00605                                                          tr("Skip information"), tr("See next"), QString(), 1, 0 );
00606                                                  else
00607                                                         k=QMessageBox::information(this, tr("FET information"), s,
00608                                                          tr("Skip information"), tr("See next"), QString(), 1, 0 );
00609                                                                                                                                                                         
00610                                                  if(k==0)
00611                                                         report=false;
00612                                           }
00613                                    }
00614                                    
00615                                    int ri=tc->rooms[ai];
00616                                    if(ri!=UNALLOCATED_SPACE && ri!=UNSPECIFIED_ROOM && lockSpace){
00617                                           ConstraintActivityPreferredRoom* ctr=new ConstraintActivityPreferredRoom(100, act->id, (gt.rules.internalRoomsList[ri])->name, false);
00618                                           bool t=gt.rules.addSpaceConstraint(ctr);
00619 
00620                                           QString s;
00621                                           
00622                                           if(t){ //modified by Volker Dirr, so you can also unlock (start)
00623                                                  addedS++;
00624                                                  idsOfLockedSpace.insert(act->id);
00625                                                  s+=tr("Added the following constraint:")+"\n"+ctr->getDetailedDescription(gt.rules);
00626                                           }
00627                                           else{
00628                                                  delete ctr;
00629                                           
00630                                                  QList<SpaceConstraint*> tmpsc;
00631                                                  tmpsc.clear();
00632                                                  int count=0;
00633                                                  foreach(SpaceConstraint* sc, gt.rules.spaceConstraintsList){
00634                                                         if(sc->type==CONSTRAINT_ACTIVITY_PREFERRED_ROOM){
00635                                                                ConstraintActivityPreferredRoom* c=(ConstraintActivityPreferredRoom*) sc;
00636                                                                if(c->activityId==act->id && c->weightPercentage==100.0 && c->active){
00637                                                                       count++;
00638                                                                       if(c->permanentlyLocked){
00639                                                                              if(idsOfLockedSpace.contains(c->activityId) || !idsOfPermanentlyLockedSpace.contains(c->activityId)){
00640                                                                                     QMessageBox::warning(this, tr("FET warning"), tr("Small problem detected")
00641                                                                                      +"\n\n"+tr("A possible problem might be that you have 2 or more constraints of type activity preferred room with weight 100% related to activity id %1, please leave only one of them").arg(act->id)
00642                                                                                      +"\n\n"+tr("A possible problem might be synchronization - so maybe try to close the timetable view dialog and open it again")
00643                                                                                      +"\n\n"+tr("Please report possible bug")
00644                                                                                      );
00645                                                                              }
00646                                                                              else{
00647                                                                                     s+=tr("Constraint %1 will not be removed, because it is permanently locked. If you want to unlock it you must go to the constraints menu.").arg("\n"+c->getDetailedDescription(gt.rules)+"\n");
00648                                                                              }
00649                                                                       }
00650                                                                       else{
00651                                                                              if(!idsOfLockedSpace.contains(c->activityId) || idsOfPermanentlyLockedSpace.contains(c->activityId)){
00652                                                                                     QMessageBox::warning(this, tr("FET warning"), tr("Small problem detected")
00653                                                                                      +"\n\n"+tr("A possible problem might be that you have 2 or more constraints of type activity preferred room with weight 100% related to activity id %1, please leave only one of them").arg(act->id)
00654                                                                                      +"\n\n"+tr("A possible problem might be synchronization - so maybe try to close the timetable view dialog and open it again")
00655                                                                                      +"\n\n"+tr("Please report possible bug")
00656                                                                                      );
00657                                                                              }
00658                                                                              else{
00659                                                                                     tmpsc.append(sc);
00660                                                                              }
00661                                                                       }
00662                                                                }
00663                                                         }
00664                                                  }
00665                                                  if(count!=1)
00666                                                         QMessageBox::warning(this, tr("FET warning"), tr("You may have a problem, because FET expected to delete 1 constraint, but will delete %1 constraints").arg(tmpsc.size()));
00667 
00668                                                  foreach(SpaceConstraint* delsc, tmpsc){
00669                                                         s+=tr("The following constraint will be deleted:")+"\n"+delsc->getDetailedDescription(gt.rules)+"\n";
00670                                                         gt.rules.removeSpaceConstraint(delsc);
00671                                                         idsOfLockedSpace.remove(act->id);
00672                                                         unlockedS++;
00673                                                         //delete delsc; done by rules.removeSpa...
00674                                                  }
00675                                                  tmpsc.clear();
00676                                                  //gt.rules.internalStructureComputed=false;
00677                                           }  //modified by Volker Dirr, so you can also unlock (end)
00678                                           
00679                                           if(report){
00680                                                  int k;
00681                                                  if(t)
00682                                                         k=QMessageBox::information(this, tr("FET information"), s,
00683                                                          tr("Skip information"), tr("See next"), QString(), 1, 0 );
00684                                                  else
00685                                                         k=QMessageBox::information(this, tr("FET information"), s,
00686                                                          tr("Skip information"), tr("See next"), QString(), 1, 0 );
00687                                                         
00688                                                  if(k==0)
00689                                                         report=false;
00690                                           }
00691                                    }
00692                             }
00693                      }
00694               }
00695        }
00696 
00697        QStringList added;
00698        QStringList removed;
00699        if(addedT>0){
00700               if(addedT==1)
00701                      added << QCoreApplication::translate("TimetableViewForm", "Added 1 locking time constraint.", "constraint is singular (only 1 constraint)");
00702               else
00703                      added << QCoreApplication::translate("TimetableViewForm", "Added %1 locking time constraints.", "%1 is >= 2, so constraints is plural").arg(addedT);
00704        }
00705        if(addedS>0){
00706               if(addedS==1)
00707                      added << QCoreApplication::translate("TimetableViewForm", "Added 1 locking space constraint.", "constraint is singular (only 1 constraint)");
00708               else
00709                      added << QCoreApplication::translate("TimetableViewForm", "Added %1 locking space constraints.", "%1 is >= 2, so constraints is plural").arg(addedS);
00710        }
00711        if(unlockedT>0){
00712               if(unlockedT==1)
00713                      removed << QCoreApplication::translate("TimetableViewForm", "Removed 1 locking time constraint.", "constraint is singular (only 1 constraint)");
00714               else
00715                      removed << QCoreApplication::translate("TimetableViewForm", "Removed %1 locking time constraints.", "%1 is >= 2, so constraints is plural").arg(unlockedT);
00716        }
00717        if(unlockedS>0){
00718               if(unlockedS==1)
00719                      removed << QCoreApplication::translate("TimetableViewForm", "Removed 1 locking space constraint.", "constraint is singular (only 1 constraint)");
00720               else
00721                      removed << QCoreApplication::translate("TimetableViewForm", "Removed %1 locking space constraints.", "%1 is >= 2, so constraints is plural").arg(unlockedS);
00722        }
00723        QString ad=added.join("\n");
00724        QString re=removed.join("\n");
00725        QStringList all;
00726        if(!ad.isEmpty())
00727               all<<ad;
00728        if(!re.isEmpty())
00729               all<<re;
00730        QString s=all.join("\n\n");
00731        if(s.isEmpty())
00732               s=QCoreApplication::translate("TimetableViewForm", "No locking constraints added or removed.");
00733        QMessageBox::information(this, tr("FET information"), s);
00734 
00736        QSet<int> backupLockedTime;
00737        QSet<int> backupPermanentlyLockedTime;
00738        QSet<int> backupLockedSpace;
00739        QSet<int> backupPermanentlyLockedSpace;
00740        
00741        backupLockedTime=idsOfLockedTime;
00742        backupPermanentlyLockedTime=idsOfPermanentlyLockedTime;
00743        backupLockedSpace=idsOfLockedSpace;
00744        backupPermanentlyLockedSpace=idsOfPermanentlyLockedSpace;
00745        
00746        LockUnlock::computeLockedUnlockedActivitiesTimeSpace(); //not needed, just for testing
00747        
00748        assert(backupLockedTime==idsOfLockedTime);
00749        assert(backupPermanentlyLockedTime==idsOfPermanentlyLockedTime);
00750        assert(backupLockedSpace==idsOfLockedSpace);
00751        assert(backupPermanentlyLockedSpace==idsOfPermanentlyLockedSpace);
00753 
00754        LockUnlock::increaseCommunicationSpinBox();
00755        
00756        //cout<<"teachers end, isc="<<gt.rules.internalStructureComputed<<endl;
00757        //cout<<endl;
00758 }
00759 
00760 void TimetableViewTeachersForm::help()
00761 {
00762        QString s="";
00763        //s+=QCoreApplication::translate("TimetableViewForm", "You can drag sections to increase/decrease them.");
00764        //s+="\n\n";
00765        s+=QCoreApplication::translate("TimetableViewForm", "Lock/unlock: you can select one or more activities in the table and toggle lock/unlock in time, space or both.");
00766        s+=" ";
00767        s+=QCoreApplication::translate("TimetableViewForm", "There will be added or removed locking constraints for the selected activities (they can be unlocked only if they are not permanently locked).");
00768        s+="\n\n";
00769        s+=QCoreApplication::translate("TimetableViewForm", "Locking time constraints are constraints of type activity preferred starting time. Locking space constraints are constraints of type"
00770               " activity preferred room. You can see these constraints in the corresponding constraints dialogs. New locking constraints are added at the end of the list of constraints.");
00771        s+="\n\n";
00772        s+=QCoreApplication::translate("TimetableViewForm", "If a cell is (permanently) locked in time or space, it contains abbreviations to show that: PLT (permanently locked time), LT (locked time), "
00773               "PLS (permanently locked space) or LS (locked space).", "Translate the abbreviations also. Make sure the abbreviations in your language are different between themselves "
00774               "and the user can differentiate easily between them. These abbreviations may appear also in other places, please use the same abbreviations.");
00775 
00776        LongTextMessageBox::largeInformation(this, tr("FET help"), s);
00777 }