Fraxinus  16.5.0-fx-rc5
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 #include "cxMultiFileInputWidget.h"
33 
34 #include <QtWidgets>
35 
36 #include <iostream>
37 
38 namespace cx
39 {
40 
41 
42 MultiFileInputWidget::MultiFileInputWidget(QWidget* parent) : QWidget(parent)
43 {
44  mBasePath = "~";
45  mUseRelativePath = false;
46  mDescription = NULL;
47  mBrowseButton = NULL;
48  mFilenameEdit = NULL;
49 
50  mLayout = new QGridLayout(this);
51  mLayout->setMargin(0);
52 
53  mFilenameEdit = new QTextEdit(this);
54  mFilenameEdit->setToolTip("File names");
55 // connect(mFilenameEdit, SIGNAL(editingFinished()), this, SIGNAL(fileChanged()));
56 // connect(mFilenameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(updateColor()));
57  connect(mFilenameEdit, SIGNAL(textChanged()), this, SLOT(evaluateTextChanges()));
58  mLayout->addWidget(mFilenameEdit, 0, 1);
59 
60  mBrowseAction = new QAction(QIcon(":/icons/open.png"), "Browse", this);
61  mBrowseAction->setStatusTip("Browse the file system");
62  connect(mBrowseAction, SIGNAL(triggered()), this, SLOT(browse()));
63 
64  mBrowseButton = new QToolButton();
65  mBrowseButton->setDefaultAction(mBrowseAction);
66  mLayout->addWidget(mBrowseButton, 0, 2);
67 }
68 
70 {
71  if (!mDescription)
72  {
73  mDescription = new QLabel(this);
74  mLayout->addWidget(mDescription, 0,0);
75  }
76 
77  mDescription->setText(text);
78 }
79 
80 void MultiFileInputWidget::setFilenames(QStringList text)
81 {
82  QStringList files = this->convertToAbsoluteFilenames(text);
83  QStringList original = this->getAbsoluteFilenames();
84 // QStringList original = this->convertToAbsoluteFilenames(mFilenameEdit->text().split('\n'));
85  if (files==original)
86  return;
87 
88  QString output = this->convertFilenamesToTextEditText(files);
89  mFilenameEdit->setText(output);
90 
91 // if (mUseRelativePath)
92 // text = QDir(mBasePath).relativeFilePath(text);
93 //
94 // if (text==mFilenameEdit->text())
95 // return;
96 // mFilenameEdit->setText(text);
97  this->widgetHasBeenChanged();
98 }
99 
100 QStringList MultiFileInputWidget::convertToAbsoluteFilenames(QStringList text) const
101 {
102  QStringList retval;
103  for (unsigned i=0; i<text.size(); ++i)
104  retval << this->convertToAbsoluteFilename(text[i]);
105  return retval;
106 }
107 QString MultiFileInputWidget::convertToAbsoluteFilename(QString text) const
108 {
109  if (text.isEmpty())
110  return text;
111  QString absolute = QDir(mBasePath).absoluteFilePath(text.trimmed());
112  QString cleaned = QDir().cleanPath(absolute);
113  if (!QFileInfo(cleaned).exists())
114  return text; // return nonexistent files unchanged.
115  return cleaned;
116 }
117 QString MultiFileInputWidget::convertFilenamesToTextEditText(QStringList files) const
118 {
119  QStringList retval;
120  for (unsigned i=0; i<files.size(); ++i)
121  {
122  retval << this->convertToPresentableFilename(files[i]);
123  }
124  return retval.join("\n");
125 }
126 
127 QString MultiFileInputWidget::convertToPresentableFilename(QString absoluteFilename) const
128 {
129  QString retval = absoluteFilename;
130  if (!QFileInfo(absoluteFilename).exists())
131  return retval;
132 
133  if (mUseRelativePath)
134  {
135  retval = QDir(mBasePath).relativeFilePath(absoluteFilename);
136  if (retval.isEmpty())
137  retval = "./"; // in order to separate from empty string (which appears during editing and should be ignored)
138  }
139 
140 
141  return retval;
142 }
143 
144 void MultiFileInputWidget::widgetHasBeenChanged()
145 {
146  this->updateHelpInternal();
147  this->updateColor();
148  emit fileChanged();
149 }
150 
152 {
153  mBaseHelp = text;
154  this->updateHelpInternal();
155 }
156 
157 void MultiFileInputWidget::updateHelpInternal()
158 {
159  QString files = this->getAbsoluteFilenames().join("\n");
160  QString text = QString("%1\n\n%2").arg(mBaseHelp).arg(files);
161  mFilenameEdit->setToolTip(text);
162  mFilenameEdit->setStatusTip(text);
163 }
164 
166 {
167  mBrowseAction->setToolTip(text);
168  mBrowseAction->setStatusTip(text);
169 }
170 
172 {
173  mBasePath = path;
174  this->widgetHasBeenChanged();
175 }
176 
177 void MultiFileInputWidget::browse()
178 {
179  QString text = "Select file";
180  if (mUseRelativePath)
181  text = QString("Select file relative to %1").arg(mBasePath);
182 
183  QString filename = QFileDialog::getExistingDirectory(this, text, mBasePath);
184  if (filename.isEmpty())
185  return;
186 // QString filename = QFileDialog::getOpenFileName(this, text, mBasePath);
187 // if (filename.isEmpty())
188 // return;
189 
190 // if (mUseRelativePath)
191 // filename = QDir(mBasePath).relativeFilePath(filename);
192 
193  QStringList files = this->getAbsoluteFilenames();
194  files << filename;
195  this->setFilenames(files);
196 }
197 
199 {
200  return mFilenameEdit->toPlainText().split('\n');
201 }
202 
204 {
205  return this->convertToAbsoluteFilenames(mFilenameEdit->toPlainText().split("\n"));
206 // QString absolute = QDir(mBasePath).absoluteFilePath(this->getFilename().trimmed());
207 // QString cleaned = QDir().cleanPath(absolute);
208 // return cleaned;
209 }
210 
212 {
213  mUseRelativePath = on;
214  this->widgetHasBeenChanged();
215 }
216 
217 void MultiFileInputWidget::evaluateTextChanges()
218 {
219  this->updateHelpInternal();
220  this->updateColor();
221  QStringList current = this->getAbsoluteFilenames();
222  if (current!=mLastFilenames)
223  {
224  mLastFilenames = current;
225  emit fileChanged();
226  }
227 }
228 
229 void MultiFileInputWidget::updateColor()
230 {
231  mFilenameEdit->blockSignals(true);
232  QTextCursor cursor = mFilenameEdit->textCursor();
233  int pos = cursor.position();
234 
235  QStringList org = mFilenameEdit->toPlainText().split("\n");
236  mFilenameEdit->setPlainText("");
237  for (int i=0; i<org.size(); ++i)
238  {
239  bool exists = QFileInfo(this->convertToAbsoluteFilename(org[i])).exists();
240 
241  if (exists)
242  mFilenameEdit->setTextColor(QColor("black"));
243  else
244  mFilenameEdit->setTextColor(QColor("red"));
245  if (i!=0)
246  mFilenameEdit->textCursor().insertText("\n");
247  mFilenameEdit->textCursor().insertText(org[i]);
248  }
249 
250  cursor.setPosition(pos);
251 
252 // QTextBlockFormat red;
253 // red.setProperty(QTextFormat::ForegroundBrush, QBrush(QColor("red")));
254 // cursor.mergeBlockFormat(red);
255  mFilenameEdit->setTextCursor(cursor);
256  mFilenameEdit->blockSignals(false);
257 
258 // QColor color = QColor("black");
259 // if (!QFileInfo(this->getAbsoluteFilename()).exists())
260 // color = QColor("red");
261 //
262 // QPalette p = mFilenameEdit->palette();
263 // p.setColor(QPalette::Text, color);
264 // mFilenameEdit->setPalette(p);
265 }
266 
267 } /* namespace cx */
MultiFileInputWidget(QWidget *parent=0)
QStringList getAbsoluteFilenames() const
void setFilenames(QStringList text)