Salome HOME
Merge branch 'master' of newgeom:newgeom.git
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetFileSelector.cpp
1 /*
2  * ModuleBase_WidgetFileSelector.cpp
3  *
4  *  Created on: Aug 28, 2014
5  *      Author: sbh
6  */
7
8 #include <ModelAPI_AttributeString.h>
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Object.h>
11 #include <ModelAPI_Validator.h>
12 #include <ModuleBase_WidgetFileSelector.h>
13 #include <ModuleBase_Tools.h>
14
15 #include <Config_WidgetAPI.h>
16
17 #include <QGridLayout>
18 #include <QFileDialog>
19 #include <QLineEdit>
20 #include <QList>
21 #include <QObject>
22 #include <QPushButton>
23 #include <QString>
24 #include <QLabel>
25
26 #include <boost/smart_ptr/shared_ptr.hpp>
27 #include <string>
28
29 ModuleBase_WidgetFileSelector::ModuleBase_WidgetFileSelector(QWidget* theParent,
30                                                              const Config_WidgetAPI* theData,
31                                                              const std::string& theParentId)
32     : ModuleBase_ModelWidget(theParent, theData, theParentId)
33 {
34   myTitle = QString::fromStdString(theData->getProperty("title"));
35   myDefaultPath = QString::fromStdString(theData->getProperty("path"));
36
37   myMainWidget = new QWidget(theParent);
38   QGridLayout* aMainLay = new QGridLayout(myMainWidget);
39   ModuleBase_Tools::adjustMargins(aMainLay);
40   QLabel* aTitleLabel = new QLabel(myTitle, myMainWidget);
41   aTitleLabel->setIndent(1);
42   aMainLay->addWidget(aTitleLabel, 0, 0);
43   myPathField = new QLineEdit(myMainWidget);
44   aMainLay->addWidget(myPathField, 1, 0);
45   QPushButton* aSelectPathBtn = new QPushButton("...", myMainWidget);
46   aSelectPathBtn->setMaximumWidth(20);
47   aSelectPathBtn->setMaximumHeight(20);
48   aMainLay->addWidget(aSelectPathBtn, 1, 1);
49   aMainLay->setColumnStretch(0, 1);
50   myPathField->setMinimumHeight(20);
51   aMainLay->setHorizontalSpacing(1);
52   myMainWidget->setLayout(aMainLay);
53
54   connect(myPathField, SIGNAL(textChanged(const QString&)),
55           this,        SLOT(onPathChanged()));
56   connect(aSelectPathBtn, SIGNAL(clicked()),
57           this,        SLOT(onPathSelectionBtn()));
58 }
59
60 ModuleBase_WidgetFileSelector::~ModuleBase_WidgetFileSelector()
61 {
62 }
63
64 bool ModuleBase_WidgetFileSelector::storeValue() const
65 {
66   // A rare case when plugin was not loaded. 
67   if(!myFeature)
68     return false;
69   DataPtr aData = myFeature->data();
70   AttributeStringPtr aStringAttr = aData->string(attributeID());
71   QString aWidgetValue = myPathField->text();
72   aStringAttr->setValue(aWidgetValue.toStdString());
73   updateObject(myFeature);
74   return true;
75 }
76
77 bool ModuleBase_WidgetFileSelector::restoreValue()
78 {
79   // A rare case when plugin was not loaded. 
80   if(!myFeature)
81     return false;
82   DataPtr aData = myFeature->data();
83   AttributeStringPtr aStringAttr = aData->string(attributeID());
84
85   bool isBlocked = myPathField->blockSignals(true);
86   myPathField->setText(QString::fromStdString(aStringAttr->value()));
87   myPathField->blockSignals(isBlocked);
88
89   return true;
90 }
91
92 QWidget* ModuleBase_WidgetFileSelector::getControl() const
93 {
94   return myMainWidget;
95 }
96
97 QList<QWidget*> ModuleBase_WidgetFileSelector::getControls() const
98 {
99   QList<QWidget*> result;
100   QPushButton * aButton = myMainWidget->findChild<QPushButton *>();
101   result << aButton;
102   result << myPathField;
103   return result;
104 }
105
106 bool ModuleBase_WidgetFileSelector::isCurrentPathValid()
107 {
108   QFileInfo aFile (myPathField->text());
109   return aFile.exists();
110 }
111
112
113 void ModuleBase_WidgetFileSelector::onPathSelectionBtn()
114 {
115   QString aFilter = formatsString();
116   QString aFileName = QFileDialog::getOpenFileName(myMainWidget, myTitle, myDefaultPath, aFilter);
117   if (!aFileName.isEmpty()) {
118     myPathField->setText(aFileName);
119   }
120 }
121
122 void ModuleBase_WidgetFileSelector::onPathChanged()
123 {
124   if(!isCurrentPathValid())
125     return;
126   storeValue();
127   emit valuesChanged();
128 }
129
130 QString ModuleBase_WidgetFileSelector::formatsString() const
131 {
132   QStringList aResult;
133   QStringList aValidatorFormats = getValidatorFormats();
134
135   foreach(QString eachFormat, aValidatorFormats)  {
136     aResult << QString("%1 files (*.%1)").arg(eachFormat);
137   }
138   aResult << QString("All files (*.*)");
139   return aResult.join(";;");
140 }
141
142 QStringList ModuleBase_WidgetFileSelector::getValidatorFormats() const
143 {
144   SessionPtr aMgr = ModelAPI_Session::get();
145   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
146   std::list<ModelAPI_Validator*> allValidators;
147   std::list<std::list<std::string> > allArguments;
148   aFactory->validators(myFeature->getKind(), myAttributeID, allValidators, allArguments);
149   //TODO(sbh): extract as separate method
150   if(allArguments.empty())
151     return QStringList();
152   std::list<std::string> anArgumentList = allArguments.front();
153   std::list<std::string>::const_iterator it = anArgumentList.begin();
154   QStringList aResult;
155   for (; it != anArgumentList.end(); ++it) {
156     std::string anArg = *it;
157     int aSepPos = anArg.find(":");
158     if (aSepPos == std::string::npos) {
159       continue;
160     }
161     QString aFormat = QString::fromStdString(anArg.substr(0, aSepPos));
162     aFormat = aFormat.toUpper();
163     aResult.append(aFormat);
164   }
165   return aResult;
166 }