Back to index

fet  5.18.0
subactivitiesform.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           subactivitiesform.cpp  -  description
00003                              -------------------
00004     begin                : 2009
00005     copyright            : (C) 2009 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 "timetable_defs.h"
00019 #include "fet.h"
00020 #include "timetable.h"
00021 
00022 #include "studentsset.h"
00023 
00024 #include "subactivitiesform.h"
00025 #include "modifysubactivityform.h"
00026 
00027 #include <QString>
00028 #include <QMessageBox>
00029 
00030 #include <QListWidget>
00031 #include <QScrollBar>
00032 
00033 #include <QAbstractItemView>
00034 
00035 #include "longtextmessagebox.h"
00036 
00037 #include <QBrush>
00038 #include <QPalette>
00039 
00040 #include <QSplitter>
00041 #include <QSettings>
00042 #include <QObject>
00043 #include <QMetaObject>
00044 
00045 extern const QString COMPANY;
00046 extern const QString PROGRAM;
00047 
00048 SubactivitiesForm::SubactivitiesForm(QWidget* parent, const QString& teacherName, const QString& studentsSetName, const QString& subjectName, const QString& activityTagName): QDialog(parent)
00049 {
00050        setupUi(this);
00051        
00052        subactivityTextEdit->setReadOnly(true);
00053        
00054        modifySubactivityPushButton->setDefault(true);
00055        
00056        subactivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00057 
00058        connect(subactivitiesListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(subactivityChanged()));
00059        connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
00060        connect(teachersComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00061        connect(studentsComboBox, SIGNAL(activated(QString)), this, SLOT(studentsFilterChanged()));
00062        connect(subjectsComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00063        connect(modifySubactivityPushButton, SIGNAL(clicked()), this, SLOT(modifySubactivity()));
00064        connect(activityTagsComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00065        connect(subactivitiesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(modifySubactivity()));
00066        connect(recursiveCheckBox, SIGNAL(toggled(bool)), this, SLOT(studentsFilterChanged()));
00067        connect(helpPushButton, SIGNAL(clicked()), this, SLOT(help()));
00068        connect(commentsPushButton, SIGNAL(clicked()), this, SLOT(subactivityComments()));
00069 
00070        centerWidgetOnScreen(this);
00071        restoreFETDialogGeometry(this);
00072        //restore splitter state
00073        QSettings settings(COMPANY, PROGRAM);
00074        if(settings.contains(this->metaObject()->className()+QString("/splitter-state")))
00075               splitter->restoreState(settings.value(this->metaObject()->className()+QString("/splitter-state")).toByteArray());
00076 
00077        QSize tmp1=teachersComboBox->minimumSizeHint();
00078        Q_UNUSED(tmp1);
00079        QSize tmp2=studentsComboBox->minimumSizeHint();
00080        Q_UNUSED(tmp2);
00081        QSize tmp3=subjectsComboBox->minimumSizeHint();
00082        Q_UNUSED(tmp3);
00083        QSize tmp4=activityTagsComboBox->minimumSizeHint();
00084        Q_UNUSED(tmp4);
00085 
00086        teachersComboBox->addItem("");
00087        int cit=0;
00088        for(int i=0; i<gt.rules.teachersList.size(); i++){
00089               Teacher* tch=gt.rules.teachersList[i];
00090               teachersComboBox->addItem(tch->name);
00091               if(tch->name==teacherName)
00092                      cit=i+1;
00093        }
00094        teachersComboBox->setCurrentIndex(cit);
00095 
00096        subjectsComboBox->addItem("");
00097        int cisu=0;
00098        for(int i=0; i<gt.rules.subjectsList.size(); i++){
00099               Subject* sb=gt.rules.subjectsList[i];
00100               subjectsComboBox->addItem(sb->name);
00101               if(sb->name==subjectName)
00102                      cisu=i+1;
00103        }
00104        subjectsComboBox->setCurrentIndex(cisu);
00105 
00106        activityTagsComboBox->addItem("");
00107        int ciat=0;
00108        for(int i=0; i<gt.rules.activityTagsList.size(); i++){
00109               ActivityTag* st=gt.rules.activityTagsList[i];
00110               activityTagsComboBox->addItem(st->name);
00111               if(st->name==activityTagName)
00112                      ciat=i+1;
00113        }
00114        activityTagsComboBox->setCurrentIndex(ciat);
00115 
00116        studentsComboBox->addItem("");
00117        int cist=0;
00118        int currentID=0;
00119        for(int i=0; i<gt.rules.yearsList.size(); i++){
00120               StudentsYear* sty=gt.rules.yearsList[i];
00121               studentsComboBox->addItem(sty->name);
00122               currentID++;
00123               if(sty->name==studentsSetName)
00124                      cist=currentID;
00125               for(int j=0; j<sty->groupsList.size(); j++){
00126                      StudentsGroup* stg=sty->groupsList[j];
00127                      studentsComboBox->addItem(stg->name);
00128                      currentID++;
00129                      if(stg->name==studentsSetName)
00130                             cist=currentID;
00131                      for(int k=0; k<stg->subgroupsList.size(); k++){
00132                             StudentsSubgroup* sts=stg->subgroupsList[k];
00133                             studentsComboBox->addItem(sts->name);
00134                             currentID++;
00135                             if(sts->name==studentsSetName)
00136                                    cist=currentID;
00137                      }
00138               }
00139        }
00140        studentsComboBox->setCurrentIndex(cist);
00141        
00142        if(studentsSetName!=""){
00143               this->studentsFilterChanged();
00144        }
00145        else{
00146               showedStudents.clear();
00147               showedStudents.insert("");
00148 
00149               this->filterChanged();
00150        }
00151 }
00152 
00153 SubactivitiesForm::~SubactivitiesForm()
00154 {
00155        saveFETDialogGeometry(this);
00156        //save splitter state
00157        QSettings settings(COMPANY, PROGRAM);
00158        settings.setValue(this->metaObject()->className()+QString("/splitter-state"), splitter->saveState());
00159 }
00160 
00161 bool SubactivitiesForm::filterOk(Activity* act)
00162 {
00163        QString tn=teachersComboBox->currentText();
00164        QString stn=studentsComboBox->currentText();
00165        QString sbn=subjectsComboBox->currentText();
00166        QString sbtn=activityTagsComboBox->currentText();
00167        int ok=true;
00168 
00169        //teacher
00170        if(tn!=""){
00171               bool ok2=false;
00172               for(QStringList::Iterator it=act->teachersNames.begin(); it!=act->teachersNames.end(); it++)
00173                      if(*it == tn){
00174                             ok2=true;
00175                             break;
00176                      }
00177               if(!ok2)
00178                      ok=false;
00179        }
00180 
00181        //subject
00182        if(sbn!="" && sbn!=act->subjectName)
00183               ok=false;
00184               
00185        //activity tag
00186        //if(sbtn!="" && sbtn!=act->activityTagName)
00187        if(sbtn!="" && !act->activityTagsNames.contains(sbtn))
00188               ok=false;
00189               
00190        //students
00191        if(stn!=""){
00192               bool ok2=false;
00193               for(QStringList::Iterator it=act->studentsNames.begin(); it!=act->studentsNames.end(); it++)
00194                      if(showedStudents.contains(*it)){
00195                             //if(*it == stn){
00196                             ok2=true;
00197                             break;
00198                      }
00199               if(!ok2)
00200                      ok=false;
00201        }
00202        else{
00203               assert(showedStudents.count()==1);
00204               assert(showedStudents.contains(""));
00205        }
00206 
00207        return ok;
00208 }
00209 
00210 void SubactivitiesForm::studentsFilterChanged()
00211 {
00212        bool showContained=recursiveCheckBox->isChecked();
00213        
00214        showedStudents.clear();
00215        
00216        if(!showContained){
00217               showedStudents.insert(studentsComboBox->currentText());
00218        }
00219        else{
00220               if(studentsComboBox->currentText()=="")
00221                      showedStudents.insert("");
00222               else{
00223                      //down
00224                      StudentsSet* set=gt.rules.searchStudentsSet(studentsComboBox->currentText());
00225                      assert(set!=NULL);
00226                      if(set->type==STUDENTS_YEAR){
00227                             StudentsYear* year=(StudentsYear*)set;
00228                             showedStudents.insert(year->name);
00229                             foreach(StudentsGroup* group, year->groupsList){
00230                                    showedStudents.insert(group->name);
00231                                    foreach(StudentsSubgroup* subgroup, group->subgroupsList)
00232                                           showedStudents.insert(subgroup->name);
00233                             }
00234                      }
00235                      else if(set->type==STUDENTS_GROUP){
00236                             StudentsGroup* group=(StudentsGroup*) set;
00237                             showedStudents.insert(group->name);
00238                             foreach(StudentsSubgroup* subgroup, group->subgroupsList)
00239                                    showedStudents.insert(subgroup->name);
00240                      }
00241                      else if(set->type==STUDENTS_SUBGROUP){
00242                             StudentsSubgroup* subgroup=(StudentsSubgroup*) set;
00243                             showedStudents.insert(subgroup->name);
00244                      }
00245                      else
00246                             assert(0);
00247 
00248                      //up
00249                      QString crt=studentsComboBox->currentText();
00250                      foreach(StudentsYear* year, gt.rules.yearsList){
00251                             foreach(StudentsGroup* group, year->groupsList){
00252                                    if(group->name==crt){
00253                                           showedStudents.insert(year->name);
00254                                    }
00255                                    foreach(StudentsSubgroup* subgroup, group->subgroupsList){
00256                                           if(subgroup->name==crt){
00257                                                  showedStudents.insert(year->name);
00258                                                  showedStudents.insert(group->name);
00259                                           }
00260                                    }
00261                             }
00262                      }
00263               }
00264        }
00265        
00266        filterChanged();
00267 }
00268 
00269 void SubactivitiesForm::filterChanged()
00270 {
00271        int nacts=0, nsubacts=0, nh=0;
00272        int ninact=0, ninacth=0;
00273 
00274 
00275        QString s;
00276        subactivitiesListWidget->clear();
00277        visibleSubactivitiesList.clear();
00278        
00279        int k=0;
00280        for(int i=0; i<gt.rules.activitiesList.size(); i++){
00281               Activity* act=gt.rules.activitiesList[i];
00282               if(this->filterOk(act)){
00283                      s=act->getDescription(gt.rules);
00284                      visibleSubactivitiesList.append(act);
00285                      subactivitiesListWidget->addItem(s);
00286                      k++;
00287                      
00288                      if(USE_GUI_COLORS && !act->active)
00289                             subactivitiesListWidget->item(k-1)->setBackground(subactivitiesListWidget->palette().alternateBase());
00290                      
00291                      if(act->id==act->activityGroupId || act->activityGroupId==0)
00292                             nacts++;
00293                      nsubacts++;
00294                      
00295                      nh+=act->duration;
00296                      
00297                      if(!act->active){
00298                             ninact++;
00299                             ninacth+=act->duration;
00300                      }
00301               }
00302        }
00303        
00304        assert(nsubacts-ninact>=0);
00305        assert(nh-ninacth>=0);
00306        activeTextLabel->setText(tr("No: %1 / %2", "No means number, %1 is the number of active activities, %2 is the number of total activities."
00307               "Please leave space between fields, so that they are better visible").arg(nsubacts-ninact).arg(nsubacts));
00308        totalTextLabel->setText(tr("Dur: %1 / %2", "Dur means duration, %1 is the duration of active activities, %2 is the duration of total activities."
00309               "Please leave space between fields, so that they are better visible").arg(nh-ninacth).arg(nh));
00310        
00311        if(subactivitiesListWidget->count()>0)
00312               subactivitiesListWidget->setCurrentRow(0);
00313        else
00314               subactivityTextEdit->setPlainText(QString(""));
00315 }
00316 
00317 void SubactivitiesForm::modifySubactivity()
00318 {
00319        int ind=subactivitiesListWidget->currentRow();
00320        if(ind<0){
00321               QMessageBox::information(this, tr("FET information"), tr("Invalid selected subactivity"));
00322               return;
00323        }
00324        
00325        assert(ind<visibleSubactivitiesList.count());
00326        
00327        int valv=subactivitiesListWidget->verticalScrollBar()->value();
00328        int valh=subactivitiesListWidget->horizontalScrollBar()->value();
00329        
00330        Activity* act=visibleSubactivitiesList[ind];
00331        assert(act!=NULL);
00332        
00333        ModifySubactivityForm modifySubactivityForm(this, act->id, act->activityGroupId);
00334        int t;
00335        setParentAndOtherThings(&modifySubactivityForm, this);
00336        t=modifySubactivityForm.exec();
00337 
00338        if(t==QDialog::Accepted){
00339               //cout<<"Acc"<<endl;
00340               filterChanged();
00341               
00342               subactivitiesListWidget->verticalScrollBar()->setValue(valv);
00343               subactivitiesListWidget->horizontalScrollBar()->setValue(valh);
00344 
00345               if(ind>=subactivitiesListWidget->count())
00346                      ind=subactivitiesListWidget->count()-1;
00347               if(ind>=0)
00348                      subactivitiesListWidget->setCurrentRow(ind);
00349        }
00350        else{
00351               //cout<<"Rej"<<endl;
00352               assert(t==QDialog::Rejected);
00353        }
00354 }
00355 
00356 void SubactivitiesForm::subactivityChanged()
00357 {
00358        int index=subactivitiesListWidget->currentRow();
00359 
00360        if(index<0){
00361               subactivityTextEdit->setPlainText(QString(""));
00362               return;
00363        }
00364        if(index>=visibleSubactivitiesList.count()){
00365               subactivityTextEdit->setPlainText(QString("Invalid subactivity"));
00366               return;
00367        }
00368 
00369        QString s;
00370        Activity* act=visibleSubactivitiesList[index];
00371 
00372        assert(act!=NULL);
00373        s=act->getDetailedDescriptionWithConstraints(gt.rules);
00374        subactivityTextEdit->setPlainText(s);
00375 }
00376 
00377 void SubactivitiesForm::help()
00378 {
00379        QString s;
00380        
00381        s+=tr("Useful instructions/tips:");
00382        s+="\n\n";
00383 
00384        s+=tr("Above the (sub)activities list, we have 2 labels, containing 4 numbers. The first label contains text: No: a / b. The first number a is the"
00385               " number of active (sub)activities (we number each individual subactivity as 1), while the second number b is the number of total (sub)activities."
00386               " The second label contains text: Dur: c / d. The third number c is the duration of active (sub)activities, in periods"
00387               " (or FET hours), while the fourth number d is the duration of total (sub)activities, in periods (or FET hours)."
00388               " So, No means number and Dur means duration.");
00389        s+="\n\n";
00390        s+=tr("Example: No: 100 / 102, Dur: 114 / 117. They represent: 100 - the number of active (sub)activities,"
00391               " then 102 - the number of total (sub)activities,"
00392               " 114 - the duration of active activities (in periods or FET hours) and 117 - the duration of total activities"
00393               " (in periods or FET hours). In this example we have 2 inactive activities with their combined duration being 3 periods.");
00394 
00395        s+="\n\n";
00396        s+=tr("Explanation of the short description of an activity: first comes the id."
00397               " If the activity is inactive, an X follows. Then the duration. Then, if the activity is split, a slash and the total duration."
00398               " Then teachers, subject, activity tag (if it is not void) and students. Then the number of students (if specified).");
00399        s+="\n\n";
00400        s+=tr("The activities which are inactive:");
00401        s+="\n";
00402        s+=" -";
00403        s+=tr("have an X mark after the id.");
00404        s+="\n";
00405 /*     s+=" -";
00406        s+=tr("are shown with lowercase letters.");
00407        s+="\n";*/
00408        s+=" -";
00409        s+=tr("if you use colors in interface (see Settings/Interface menu), they will appear with different background color.");
00410        s+="\n\n";
00411        s+=tr("To modify a subactivity, you can also double click it.");
00412        s+="\n\n";
00413        s+=tr("Show related: if you select this, there will be listed subactivities for groups and subgroups contained also in the current set (if the current set"
00414               " is a year or a group) and also higher ranked year or group (if the current set is a group or a subgroup).");
00415        
00416        LongTextMessageBox::largeInformation(this, tr("FET Help"), s);
00417 }
00418 
00419 void SubactivitiesForm::subactivityComments()
00420 {
00421        int ind=subactivitiesListWidget->currentRow();
00422        if(ind<0){
00423               QMessageBox::information(this, tr("FET information"), tr("Invalid selected subactivity"));
00424               return;
00425        }
00426        
00427        assert(ind<visibleSubactivitiesList.count());
00428 
00429        Activity* act=visibleSubactivitiesList[ind];
00430        assert(act!=NULL);
00431 
00432        QDialog getCommentsDialog(this);
00433        
00434        getCommentsDialog.setWindowTitle(tr("Subactivity comments"));
00435        
00436        QPushButton* okPB=new QPushButton(tr("OK"));
00437        okPB->setDefault(true);
00438        QPushButton* cancelPB=new QPushButton(tr("Cancel"));
00439        
00440        connect(okPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(accept()));
00441        connect(cancelPB, SIGNAL(clicked()), &getCommentsDialog, SLOT(reject()));
00442 
00443        QHBoxLayout* hl=new QHBoxLayout();
00444        hl->addStretch();
00445        hl->addWidget(okPB);
00446        hl->addWidget(cancelPB);
00447        
00448        QVBoxLayout* vl=new QVBoxLayout();
00449        
00450        QPlainTextEdit* commentsPT=new QPlainTextEdit();
00451        commentsPT->setPlainText(act->comments);
00452        commentsPT->selectAll();
00453        commentsPT->setFocus();
00454        
00455        vl->addWidget(commentsPT);
00456        vl->addLayout(hl);
00457        
00458        getCommentsDialog.setLayout(vl);
00459        
00460        const QString settingsName=QString("SubactivityCommentsDialog");
00461        
00462        getCommentsDialog.resize(500, 320);
00463        centerWidgetOnScreen(&getCommentsDialog);
00464        restoreFETDialogGeometry(&getCommentsDialog, settingsName);
00465        
00466        int t=getCommentsDialog.exec();
00467        saveFETDialogGeometry(&getCommentsDialog, settingsName);
00468        
00469        if(t==QDialog::Accepted){
00470               act->comments=commentsPT->toPlainText();
00471        
00472               gt.rules.internalStructureComputed=false;
00473               setRulesModifiedAndOtherThings(&gt.rules);
00474 
00475               subactivitiesListWidget->currentItem()->setText(act->getDescription(gt.rules));
00476               subactivityChanged();
00477        }
00478 }