15
15
******************************************************************************/
16
16
17
17
#include " customelements.h"
18
+ #include " backgroundfileformat.h"
18
19
19
20
#include < avogadro/qtgui/customelementdialog.h>
21
+ #include < avogadro/qtgui/fileformatdialog.h>
20
22
#include < avogadro/qtgui/molecule.h>
21
23
24
+ #include < QtCore/QSettings>
25
+ #include < QtCore/QThread>
22
26
#include < QtWidgets/QAction>
27
+ #include < QtWidgets/QMessageBox>
28
+ #include < QtWidgets/QProgressDialog>
23
29
24
30
using Avogadro::QtGui::Molecule;
25
31
26
32
namespace Avogadro {
27
33
namespace QtPlugins {
28
34
29
35
CustomElements::CustomElements (QObject* parent_)
30
- : Avogadro::QtGui::ExtensionPlugin(parent_), m_molecule(nullptr ),
31
- m_reassignAction (new QAction(tr(" Reassign &Custom Elements..." ), this))
36
+ : Avogadro::QtGui::ExtensionPlugin(parent_)
37
+ , m_molecule(nullptr )
38
+ , m_reassignUsingTool(nullptr )
39
+ , m_reassignFromFile(nullptr )
40
+ , m_fileReadThread(nullptr )
41
+ , m_threadedReader(nullptr )
42
+ , m_fileReadMolecule(nullptr )
43
+ , m_progressDialog(nullptr )
32
44
{
33
- connect (m_reassignAction, SIGNAL (triggered ()), SLOT (reassign ()));
45
+ m_reassignUsingTool = new QAction (tr (" Using &Mapping tool..." ), this );
46
+ m_reassignFromFile = new QAction (tr (" From &File..." ), this );
47
+ connect (m_reassignUsingTool, SIGNAL (triggered ()), SLOT (reassign ()));
48
+ connect (m_reassignFromFile, SIGNAL (triggered ()), SLOT (importMapFile ()));
34
49
35
50
updateReassignAction ();
36
51
}
37
52
38
- CustomElements::~CustomElements ()
39
- {
40
- }
53
+ CustomElements::~CustomElements () {}
41
54
42
55
QString CustomElements::description () const
43
56
{
@@ -46,12 +59,12 @@ QString CustomElements::description() const
46
59
47
60
QList<QAction*> CustomElements::actions () const
48
61
{
49
- return QList<QAction*>() << m_reassignAction ;
62
+ return QList<QAction*>() << m_reassignUsingTool << m_reassignFromFile ;
50
63
}
51
64
52
65
QStringList CustomElements::menuPath (QAction*) const
53
66
{
54
- return QStringList () << tr (" &Build" );
67
+ return QStringList () << tr (" &Build" ) << tr ( " Assign &Custom Elements... " ) ;
55
68
}
56
69
57
70
void CustomElements::setMolecule (QtGui::Molecule* mol)
@@ -86,9 +99,123 @@ void CustomElements::reassign()
86
99
}
87
100
}
88
101
102
+ bool CustomElements::openFile (const QString& fileName, Io::FileFormat* reader)
103
+ {
104
+ if (fileName.isEmpty () || reader == nullptr ) {
105
+ delete reader;
106
+ return false ;
107
+ }
108
+
109
+ QString ident = QString::fromStdString (reader->identifier ());
110
+
111
+ // Prepare the background thread to read in the selected file.
112
+ if (!m_fileReadThread)
113
+ m_fileReadThread = new QThread (qobject_cast<QWidget*>(parent ()));
114
+ if (m_threadedReader)
115
+ m_threadedReader->deleteLater ();
116
+ m_threadedReader = new BackgroundFileFormat (reader);
117
+ if (m_fileReadMolecule)
118
+ m_fileReadMolecule->deleteLater ();
119
+ m_fileReadMolecule = new Molecule (qobject_cast<QWidget*>(parent ()));
120
+ m_fileReadMolecule->setData (" fileName" , fileName.toLocal8Bit ().data ());
121
+ m_threadedReader->moveToThread (m_fileReadThread);
122
+ m_threadedReader->setMolecule (m_fileReadMolecule);
123
+ m_threadedReader->setFileName (fileName);
124
+
125
+ // Setup a progress dialog in case file loading is slow
126
+ m_progressDialog = new QProgressDialog (qobject_cast<QWidget*>(parent ()));
127
+ m_progressDialog->setRange (0 , 0 );
128
+ m_progressDialog->setValue (0 );
129
+ m_progressDialog->setMinimumDuration (750 );
130
+ m_progressDialog->setWindowTitle (tr (" Reading File" ));
131
+ m_progressDialog->setLabelText (
132
+ tr (" Opening file '%1'\n with '%2'" ).arg (fileName).arg (ident));
133
+ // / @todo Add API to abort file ops
134
+ m_progressDialog->setCancelButton (nullptr );
135
+ connect (m_fileReadThread, SIGNAL (started ()), m_threadedReader, SLOT (read ()));
136
+ connect (m_threadedReader, SIGNAL (finished ()), m_fileReadThread, SLOT (quit ()));
137
+ connect (m_threadedReader, SIGNAL (finished ()),
138
+ SLOT (backgroundReaderFinished ()));
139
+
140
+ // Start the file operation
141
+ m_fileReadThread->start ();
142
+ m_progressDialog->show ();
143
+
144
+ return true ;
145
+ }
146
+
147
+ void CustomElements::backgroundReaderFinished ()
148
+ {
149
+ QString fileName = m_threadedReader->fileName ();
150
+ if (m_progressDialog->wasCanceled ()) {
151
+ delete m_fileReadMolecule;
152
+ } else if (m_threadedReader->success ()) {
153
+ if (!fileName.isEmpty ()) {
154
+ m_fileReadMolecule->setData (" fileName" , fileName.toLocal8Bit ().data ());
155
+ } else {
156
+ m_fileReadMolecule->setData (" fileName" , Core::Variant ());
157
+ }
158
+ setMapFromMolecule (m_fileReadMolecule);
159
+ } else {
160
+ QMessageBox::critical (qobject_cast<QWidget*>(parent ()), tr (" File error" ),
161
+ tr (" Error while reading file '%1':\n %2" )
162
+ .arg (fileName)
163
+ .arg (m_threadedReader->error ()));
164
+ delete m_fileReadMolecule;
165
+ }
166
+ m_fileReadThread->deleteLater ();
167
+ m_fileReadThread = nullptr ;
168
+ m_threadedReader->deleteLater ();
169
+ m_threadedReader = nullptr ;
170
+ m_fileReadMolecule = nullptr ;
171
+ m_progressDialog->hide ();
172
+ m_progressDialog->deleteLater ();
173
+ m_progressDialog = nullptr ;
174
+ }
175
+
176
+ void CustomElements::setMapFromMolecule (QtGui::Molecule* mol)
177
+ {
178
+ if (mol->atomCount () != m_molecule->atomCount ()) {
179
+ QMessageBox::critical (
180
+ qobject_cast<QWidget*>(parent ()), tr (" Error" ),
181
+ tr (" Atom count mismatch.\n Expected %1 atoms, found %2." )
182
+ .arg (m_molecule->atomCount ())
183
+ .arg (mol->atomCount ()));
184
+ } else {
185
+ size_t n = m_molecule->atomCount ();
186
+ for (size_t i = 0 ; i < n; ++i) {
187
+ m_molecule->atom (i).setAtomicNumber (mol->atom (i).atomicNumber ());
188
+ }
189
+ m_molecule->emitChanged (Molecule::Atoms | Molecule::Modified);
190
+ }
191
+ }
192
+
193
+ void CustomElements::importMapFile ()
194
+ {
195
+ QSettings settings;
196
+ QString dir = settings.value (" MainWindow/lastOpenDir" ).toString ();
197
+
198
+ QtGui::FileFormatDialog::FormatFilePair reply =
199
+ QtGui::FileFormatDialog::fileToRead (qobject_cast<QWidget*>(parent ()),
200
+ tr (" Open Molecule" ), dir);
201
+
202
+ if (reply.first == NULL ) // user cancel
203
+ return ;
204
+
205
+ dir = QFileInfo (reply.second ).absoluteDir ().absolutePath ();
206
+ settings.setValue (" MainWindow/lastOpenDir" , dir);
207
+
208
+ if (!openFile (reply.second , reply.first ->newInstance ())) {
209
+ QMessageBox::information (
210
+ qobject_cast<QWidget*>(parent ()), tr (" Cannot open file" ),
211
+ tr (" Can't open supplied file %1" ).arg (reply.second ));
212
+ }
213
+ }
214
+
89
215
void CustomElements::updateReassignAction ()
90
216
{
91
- m_reassignAction->setEnabled (m_molecule && m_molecule->hasCustomElements ());
217
+ m_reassignUsingTool->setEnabled (m_molecule);
218
+ m_reassignFromFile->setEnabled (m_molecule);
92
219
}
93
220
94
221
} // namespace QtPlugins
0 commit comments