CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxMultiFileInputWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 #include "cxMultiFileInputWidget.h"
12 
13 #include <QtWidgets>
14 
15 #include <iostream>
16 
17 namespace cx
18 {
19 
20 
21 MultiFileInputWidget::MultiFileInputWidget(QWidget* parent) : QWidget(parent)
22 {
23  mBasePath = "~";
24  mUseRelativePath = false;
25  mDescription = NULL;
26  mBrowseButton = NULL;
27  mFilenameEdit = NULL;
28 
29  mLayout = new QGridLayout(this);
30  mLayout->setMargin(0);
31 
32  mFilenameEdit = new QTextEdit(this);
33  mFilenameEdit->setToolTip("File names");
34 // connect(mFilenameEdit, SIGNAL(editingFinished()), this, SIGNAL(fileChanged()));
35 // connect(mFilenameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(updateColor()));
36  connect(mFilenameEdit, SIGNAL(textChanged()), this, SLOT(evaluateTextChanges()));
37  mLayout->addWidget(mFilenameEdit, 0, 1);
38 
39  mBrowseAction = new QAction(QIcon(":/icons/open.png"), "Browse", this);
40  mBrowseAction->setStatusTip("Browse the file system");
41  connect(mBrowseAction, SIGNAL(triggered()), this, SLOT(browse()));
42 
43  mBrowseButton = new QToolButton();
44  mBrowseButton->setDefaultAction(mBrowseAction);
45  mLayout->addWidget(mBrowseButton, 0, 2);
46 }
47 
49 {
50  if (!mDescription)
51  {
52  mDescription = new QLabel(this);
53  mLayout->addWidget(mDescription, 0,0);
54  }
55 
56  mDescription->setText(text);
57 }
58 
59 void MultiFileInputWidget::setFilenames(QStringList text)
60 {
61  QStringList files = this->convertToAbsoluteFilenames(text);
62  QStringList original = this->getAbsoluteFilenames();
63 // QStringList original = this->convertToAbsoluteFilenames(mFilenameEdit->text().split('\n'));
64  if (files==original)
65  return;
66 
67  QString output = this->convertFilenamesToTextEditText(files);
68  mFilenameEdit->setText(output);
69 
70 // if (mUseRelativePath)
71 // text = QDir(mBasePath).relativeFilePath(text);
72 //
73 // if (text==mFilenameEdit->text())
74 // return;
75 // mFilenameEdit->setText(text);
76  this->widgetHasBeenChanged();
77 }
78 
79 QStringList MultiFileInputWidget::convertToAbsoluteFilenames(QStringList text) const
80 {
81  QStringList retval;
82  for (unsigned i=0; i<text.size(); ++i)
83  retval << this->convertToAbsoluteFilename(text[i]);
84  return retval;
85 }
86 QString MultiFileInputWidget::convertToAbsoluteFilename(QString text) const
87 {
88  if (text.isEmpty())
89  return text;
90  QString absolute = QDir(mBasePath).absoluteFilePath(text.trimmed());
91  QString cleaned = QDir().cleanPath(absolute);
92  if (!QFileInfo(cleaned).exists())
93  return text; // return nonexistent files unchanged.
94  return cleaned;
95 }
96 QString MultiFileInputWidget::convertFilenamesToTextEditText(QStringList files) const
97 {
98  QStringList retval;
99  for (unsigned i=0; i<files.size(); ++i)
100  {
101  retval << this->convertToPresentableFilename(files[i]);
102  }
103  return retval.join("\n");
104 }
105 
106 QString MultiFileInputWidget::convertToPresentableFilename(QString absoluteFilename) const
107 {
108  QString retval = absoluteFilename;
109  if (!QFileInfo(absoluteFilename).exists())
110  return retval;
111 
112  if (mUseRelativePath)
113  {
114  retval = QDir(mBasePath).relativeFilePath(absoluteFilename);
115  if (retval.isEmpty())
116  retval = "./"; // in order to separate from empty string (which appears during editing and should be ignored)
117  }
118 
119 
120  return retval;
121 }
122 
123 void MultiFileInputWidget::widgetHasBeenChanged()
124 {
125  this->updateHelpInternal();
126  this->updateColor();
127  emit fileChanged();
128 }
129 
131 {
132  mBaseHelp = text;
133  this->updateHelpInternal();
134 }
135 
136 void MultiFileInputWidget::updateHelpInternal()
137 {
138  QString files = this->getAbsoluteFilenames().join("\n");
139  QString text = QString("%1\n\n%2").arg(mBaseHelp).arg(files);
140  mFilenameEdit->setToolTip(text);
141  mFilenameEdit->setStatusTip(text);
142 }
143 
145 {
146  mBrowseAction->setToolTip(text);
147  mBrowseAction->setStatusTip(text);
148 }
149 
151 {
152  mBasePath = path;
153  this->widgetHasBeenChanged();
154 }
155 
156 void MultiFileInputWidget::browse()
157 {
158  QString text = "Select file";
159  if (mUseRelativePath)
160  text = QString("Select file relative to %1").arg(mBasePath);
161 
162  QString filename = QFileDialog::getExistingDirectory(this, text, mBasePath);
163  if (filename.isEmpty())
164  return;
165 // QString filename = QFileDialog::getOpenFileName(this, text, mBasePath);
166 // if (filename.isEmpty())
167 // return;
168 
169 // if (mUseRelativePath)
170 // filename = QDir(mBasePath).relativeFilePath(filename);
171 
172  QStringList files = this->getAbsoluteFilenames();
173  files << filename;
174  this->setFilenames(files);
175 }
176 
178 {
179  return mFilenameEdit->toPlainText().split('\n');
180 }
181 
183 {
184  return this->convertToAbsoluteFilenames(mFilenameEdit->toPlainText().split("\n"));
185 // QString absolute = QDir(mBasePath).absoluteFilePath(this->getFilename().trimmed());
186 // QString cleaned = QDir().cleanPath(absolute);
187 // return cleaned;
188 }
189 
191 {
192  mUseRelativePath = on;
193  this->widgetHasBeenChanged();
194 }
195 
196 void MultiFileInputWidget::evaluateTextChanges()
197 {
198  this->updateHelpInternal();
199  this->updateColor();
200  QStringList current = this->getAbsoluteFilenames();
201  if (current!=mLastFilenames)
202  {
203  mLastFilenames = current;
204  emit fileChanged();
205  }
206 }
207 
208 void MultiFileInputWidget::updateColor()
209 {
210  mFilenameEdit->blockSignals(true);
211  QTextCursor cursor = mFilenameEdit->textCursor();
212  int pos = cursor.position();
213 
214  QStringList org = mFilenameEdit->toPlainText().split("\n");
215  mFilenameEdit->setPlainText("");
216  for (int i=0; i<org.size(); ++i)
217  {
218  bool exists = QFileInfo(this->convertToAbsoluteFilename(org[i])).exists();
219 
220  if (exists)
221  mFilenameEdit->setTextColor(QColor("black"));
222  else
223  mFilenameEdit->setTextColor(QColor("red"));
224  if (i!=0)
225  mFilenameEdit->textCursor().insertText("\n");
226  mFilenameEdit->textCursor().insertText(org[i]);
227  }
228 
229  cursor.setPosition(pos);
230 
231 // QTextBlockFormat red;
232 // red.setProperty(QTextFormat::ForegroundBrush, QBrush(QColor("red")));
233 // cursor.mergeBlockFormat(red);
234  mFilenameEdit->setTextCursor(cursor);
235  mFilenameEdit->blockSignals(false);
236 
237 // QColor color = QColor("black");
238 // if (!QFileInfo(this->getAbsoluteFilename()).exists())
239 // color = QColor("red");
240 //
241 // QPalette p = mFilenameEdit->palette();
242 // p.setColor(QPalette::Text, color);
243 // mFilenameEdit->setPalette(p);
244 }
245 
246 } /* namespace cx */
MultiFileInputWidget(QWidget *parent=0)
QStringList getAbsoluteFilenames() const
void setFilenames(QStringList text)
Namespace for all CustusX production code.