Back to index

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