1 #include "ImageFileListWidget.h" 6 #include <QApplication> 7 #include <QContextMenuEvent> 10 #include <QInputDialog> 11 #include <QHBoxLayout> 15 #include <QPushButton> 16 #include <QScrollArea> 20 #include <QVBoxLayout> 21 #include <QXmlStreamWriter> 27 #include "ImageTreeWidget.h" 28 #include "ImageTreeWidgetItem.h" 30 #include "ProgressBar.h" 35 #include "XmlStackedHandlerReader.h" 50 QHBoxLayout *layout =
new QHBoxLayout();
53 m_tree->setObjectName(
"Tree");
56 layout->setContentsMargins(0, 0, 0, 0);
58 setWhatsThis(
"This is the image file list. Opened " 59 "cubes show up here. You can arrange your cubes into groups (that you " 60 "name) to help keep track of them. Also, you can configure multiple " 61 "files at once. Finally, you can sort your files by any of the visible " 62 "columns (use the view menu to show/hide columns of data).");
64 treeWidget->setLayout(layout);
71 m_searchToolbar->setWhatsThis(
"This contains all the fields for searching the active file list");
73 m_searchLineEdit =
new QLineEdit();
74 QPushButton *okButton =
new QPushButton(
"Search");
75 connect(okButton, SIGNAL(clicked()),
this, SLOT(filterFileList()));
76 QPushButton *clearButton =
new QPushButton(
"Clear");
77 connect(clearButton, SIGNAL(clicked()),
this, SLOT(clear()));
78 QHBoxLayout *actionLayout =
new QHBoxLayout();
79 m_fileCount =
new QLabel(
"File Matches: 0");
80 actionLayout->addWidget(m_searchLineEdit);
81 actionLayout->addWidget(okButton);
82 actionLayout->addWidget(clearButton);
83 actionLayout->addWidget(m_fileCount);
84 actionLayout->addStretch(1);
85 actionLayout->setMargin(0);
87 toolBarWidget->setLayout(actionLayout);
89 QVBoxLayout *fileListWidgetLayout =
new QVBoxLayout();
91 fileListWidgetLayout->addWidget(treeWidget);
92 setLayout(fileListWidgetLayout);
120 if (pvl.
name() ==
"ImageFileList") {
122 ImageTreeWidgetItem::TreeColumn col =
123 ImageTreeWidgetItem::FootprintColumn;
124 while (col < ImageTreeWidgetItem::BlankColumn) {
125 IString key = ImageTreeWidgetItem::treeColumnToString(col) +
"Visible";
139 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
143 m_tree->sortItems(pvl[
"SortColumn"], Qt::AscendingOrder);
148 while (
m_tree->topLevelItemCount() > 0) {
150 allCubes.append(group->takeChildren());
157 for (
int cubeGrp = 0; cubeGrp < pvl.
objects(); cubeGrp ++) {
163 bool expanded = (cubes[
"Expanded"][0] !=
"No");
164 newCubeGrp->setExpanded(expanded);
168 if (allCubes.size()) {
169 m_tree->addGroup(
"",
"Unknown")->addChildren(allCubes);
186 ImageTreeWidgetItem::TreeColumn col =
187 ImageTreeWidgetItem::FootprintColumn;
188 while (col < ImageTreeWidgetItem::BlankColumn) {
189 IString key = ImageTreeWidgetItem::treeColumnToString(col) +
"Visible";
191 bool visible = !
m_tree->isColumnHidden(col);
194 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
200 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
203 group->text(ImageTreeWidgetItem::NameColumn));
204 cubeGroup +=
PvlKeyword(
"Expanded", group->isExpanded() ?
"Yes" :
"No");
206 for (
int j = 0; j < group->childCount(); j++) {
209 if (item->type() == QTreeWidgetItem::UserType) {
212 cubeGroup +=
PvlKeyword(
"Image", cubeItem->image()->
id());
241 return m_tree->getViewActions();
255 "Save Entire Cube List (ordered by &file list/groups)...");
269 QScrollArea *longHelpWidgetScrollArea =
new QScrollArea;
272 longHelpWidgetScrollArea->setWidget(longHelpWidget);
274 QVBoxLayout *longHelpLayout =
new QVBoxLayout;
275 longHelpLayout->setSizeConstraint(QLayout::SetFixedSize);
276 longHelpWidget->setLayout(longHelpLayout);
278 QLabel *title =
new QLabel(
"<h2>Image File List</h2>");
279 longHelpLayout->addWidget(title);
282 if (!fileListContainer) {
288 tmp->resize(QSize(500, 200));
289 preview = tmp->grab();
293 QPixmap previewPixmap = fileListContainer->grab().scaled(
294 QSize(500, 200), Qt::KeepAspectRatio, Qt::SmoothTransformation);
296 QLabel *previewWrapper =
new QLabel;
297 previewWrapper->setPixmap(previewPixmap);
298 longHelpLayout->addWidget(previewWrapper);
301 QLabel *previewWrapper =
new QLabel;
302 previewWrapper->setPixmap(preview);
303 longHelpLayout->addWidget(previewWrapper);
305 QLabel *overview =
new QLabel(tr(
"The mosaic file list is designed to help " 306 "to organize your files within the %1 project. The file list supports changing multiple " 307 "files simultaneously using the right-click menus after selecting " 308 "several images or groups.<br>" 310 "<p>Every cube must be inside of a group. These groups can be " 311 "renamed by double clicking on them. To move a cube between groups, " 312 "click and drag it to the group you want it in. This works " 313 "for multiple cubes also. You can change all of the cubes in a " 314 "group by right clicking on the group name. You can add a group " 315 "by right clicking in the white space below the last cube or on " 316 "an existing group.</p>" 318 "Show and hide columns by using the view menu. These " 319 "columns show relevant data about the cube, including statistical " 320 "information. Some of this information will be blank if you do " 321 "not run the application, <i>camstats</i>, before opening the cube." 323 "Sort cubes within each group in ascending or descending order " 324 "by clicking on the column " 325 "title of the column that you want to sort on. Clicking on the " 326 "title again will reverse the sorting order. You can also drag and " 327 "drop a cube between two other cubes to change where it is in the " 328 "list.").arg(QApplication::applicationName()));
329 overview->setWordWrap(
true);
331 longHelpLayout->addWidget(overview);
332 longHelpLayout->addStretch();
334 return longHelpWidgetScrollArea;
361 while (
m_tree->topLevelItemCount()) {
362 groups.append(
m_tree->takeTopLevelItem(0));
367 foreach (
Image *image, *images) {
368 if (alreadyViewedImages.indexOf(image) == -1) {
371 if (!m_serialized.isNull()) {
377 if (!pos.isValid()) {
378 if (
m_tree->groupInList(selected)) {
379 QListIterator<QTreeWidgetItem *> it(selected);
380 while (it.hasNext() && !selectedGroup) {
382 if (item->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageGroupType) {
383 selectedGroup = item;
388 if (!selectedGroup) {
392 if (images->
name().isEmpty()) {
393 imageListNameItem =
m_tree->invisibleRootItem();
394 groupName = QString(
"Group %1").arg(groups.count() + 1);
397 for (
int i = 0; !imageListNameItem && i < groups.count(); i++) {
399 if (group->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageListNameType &&
400 group->text(0) == images->
name()) {
401 imageListNameItem = group;
405 if (!imageListNameItem) {
406 imageListNameItem =
m_tree->createImageListNameItem(images->
name());
407 groups.append(imageListNameItem);
411 selectedGroup =
m_tree->createGroup(imageListNameItem, groupName);
414 selectedGroup->addChild(newImageItem);
418 if (groupItem->childCount() < pos.index())
419 groupItem->addChild(newImageItem);
421 groupItem->insertChild(pos.index(), newImageItem);
429 m_tree->addTopLevelItem(group);
434 selectedGroup->setSelected(
true);
447 foreach (
Image* image, *images) {
449 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
452 for (
int j = 0; j < group->childCount(); j++) {
455 if (item->type() == QTreeWidgetItem::UserType && !item->isHidden()) {
457 if (cubeItem->image() == image){
458 item->setHidden(
true);
488 menu.exec(event->globalPos());
496 QFileDialog::getSaveFileName((
QWidget *)parent(),
497 "Choose output file",
498 QDir::currentPath() +
"/files.lis",
499 QString(
"List File (*.lis);;Text File (*.txt);;All Files (*.*)"));
500 if (output.isEmpty())
return;
504 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
507 for (
int j = 0; j < group->childCount(); j++) {
510 if (item->type() == QTreeWidgetItem::UserType) {
526 QString
id = image->
id();
529 for (
int objIndex = 0; !result.isValid() && objIndex < m_serialized->objects(); objIndex++) {
530 PvlObject &obj = m_serialized->object(objIndex);
532 int imageKeyOffset = 0;
533 for (
int fileKeyIndex = 0;
534 !result.isValid() && fileKeyIndex < obj.
keywords();
561 if (states.contains(
"Expanded")) {
562 item->setExpanded(states[
"Expanded"].
toBool());
565 item->setExpanded(
true);
571 while (i < item->childCount() && i < childrenStates.count()) {
576 while (i < item->childCount()) {
592 result[
"Expanded"] = item->isExpanded();
594 if (item->childCount()) {
597 for (
int i = 0; i < item->childCount(); i++) {
601 result[
"Children"] = childrenStates;
629 stream.writeStartElement(
"imageFileList");
630 stream.writeAttribute(
"objectName", objectName());
660 ImageTreeWidgetItem::TreeColumn col =
661 ImageTreeWidgetItem::FootprintColumn;
662 while (col < ImageTreeWidgetItem::BlankColumn) {
663 bool visible = !
m_tree->isColumnHidden(col);
664 bool sorted = (
m_tree->sortColumn() == col);
666 stream.writeStartElement(
"column");
667 stream.writeAttribute(
"name", ImageTreeWidgetItem::treeColumnToString(col));
668 stream.writeAttribute(
"visible", (visible?
"true" :
"false"));
669 stream.writeAttribute(
"sorted", (sorted?
"true" :
"false"));
670 stream.writeEndElement();
672 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
678 stream.writeEndElement();
694 stream.writeStartElement(
"treeLayout");
696 else if (itemToWrite->type() == QTreeWidgetItem::UserType) {
699 stream.writeStartElement(
"image");
700 stream.writeAttribute(
"id", imageItemToWrite->image()->
id());
703 bool groupIsImageList =
704 (itemToWrite->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageListNameType);
706 stream.writeStartElement(
"group");
707 stream.writeAttribute(
"name", itemToWrite->text(ImageTreeWidgetItem::NameColumn));
708 stream.writeAttribute(
"expanded", itemToWrite->isExpanded() ?
"true" :
"false");
709 stream.writeAttribute(
"isImageList", groupIsImageList?
"true" :
"false");
717 if (itemToWrite == NULL && i < m_tree->topLevelItemCount()) {
718 childItemToWrite =
m_tree->topLevelItem(i);
720 else if (itemToWrite != NULL && i < itemToWrite->childCount()) {
721 childItemToWrite = itemToWrite->child(i);
724 if (childItemToWrite) {
725 save(stream, childItemToWrite);
728 done = (childItemToWrite == NULL);
733 stream.writeEndElement();
766 const QString &localName,
const QString &qName,
const QXmlAttributes &atts) {
767 bool result = XmlStackedHandler::startElement(namespaceURI, localName, qName, atts);
776 if (localName ==
"position") {
777 QPoint pos = QPoint(atts.value(
"x").toInt(), atts.value(
"y").toInt());
779 m_fileList->move(pos);
781 else if (localName ==
"size") {
782 QSize size = QSize(atts.value(
"width").toInt(), atts.value(
"height").toInt());
784 m_fileList->resize(size);
786 else if (localName ==
"column") {
787 QString colName = atts.value(
"name");
788 QString colVisibleStr = atts.value(
"visible");
789 QString colSortedStr = atts.value(
"sorted");
792 ImageTreeWidgetItem::TreeColumn col =
793 ImageTreeWidgetItem::NameColumn;
794 while (col < ImageTreeWidgetItem::BlankColumn) {
795 QString curColName = ImageTreeWidgetItem::treeColumnToString(col);
797 if (curColName == colName) {
798 if (colVisibleStr !=
"false") {
799 m_fileList->m_tree->showColumn(col);
802 m_fileList->m_tree->hideColumn(col);
805 if (colSortedStr ==
"true") {
806 m_fileList->m_tree->sortItems(col, Qt::AscendingOrder);
810 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
814 else if (localName ==
"group") {
815 if (atts.value(
"isImageList") ==
"true") {
816 if (!m_currentImageList) {
817 QString name = atts.value(
"name");
818 m_currentImageListItem = m_fileList->m_tree->createImageListNameItem(name);
819 m_currentImageList = m_fileList->m_directory->project()->imageList(name);
820 m_fileList->m_tree->addTopLevelItem(m_currentImageListItem);
821 m_currentImageListItem->setExpanded(
true);
825 m_currentGroup = m_fileList->m_tree->createGroup(m_currentImageListItem,
830 else if (localName ==
"image" && m_currentGroup) {
831 Image *image = m_fileList->m_directory->project()->image(atts.value(
"id"));
835 Shape *shape = m_fileList->m_directory->project()->shape(atts.value(
"id"));
840 m_currentGroup->addChild(m_fileList->m_tree->prepCube(m_currentImageList, image));
859 const QString &localName,
const QString &qName) {
860 bool result = XmlStackedHandler::endElement(namespaceURI, localName, qName);
863 if (localName ==
"group") {
864 if (m_currentGroup) {
865 m_currentGroup = NULL;
868 m_currentImageList = NULL;
869 m_currentImageListItem = NULL;
878 void ImageFileListWidget::filterFileList() {
879 QString filterString = m_searchLineEdit->text();
882 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
885 for (
int j = 0; j < group->childCount(); j++) {
887 group->setSelected(
false);
888 if (item->type() == QTreeWidgetItem::UserType) {
891 if (cubeItem->image()->
fileName().contains(filterString)){
892 cubeItem->setSelected(
true);
893 m_tree->scrollToItem(cubeItem);
897 cubeItem->setSelected(
false);
902 m_fileCount->setText(
"File Matches: " + QString::number(numMatches));
906 void ImageFileListWidget::clear() {
907 m_searchLineEdit->setText(
"");
908 m_fileCount->setText(
"File Matches: 0");
910 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
913 for (
int j = 0; j < group->childCount(); j++) {
915 group->setSelected(
false);
916 if (item->type() == QTreeWidgetItem::UserType) {
917 item->setSelected(
false);
PvlObject & object(const int index)
Return the object at the specified index.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
QString name() const
Get the human-readable name of this image list.
Internalizes a list of images and allows for operations on the entire list.
The main project for ipce.
File name manipulation and expansion.
int objects() const
Returns the number of objects.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
A type of error that occurred when performing an actual I/O operation.
bool isNamed(QString name) const
Determines whether two PvlKeywords have the same name or not.
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
QString name() const
Returns the container name.
Cube * cube()
Get the Cube * associated with this display property.
#define _FILEINFO_
Macro for the filename and line number.
IString Convert(const std::string &listofchars, const char &to)
Returns the string with all occurrences of any character in the "from" argument converted to the "to"...
A single keyword-value pair.
virtual void pushContentHandler(XmlStackedHandler *newHandler)
Push a contentHandler and maybe continue parsing...
QString ToQt() const
Retuns the object string as a QString.
This represents a cube in a project-based GUI interface.
geos::geom::MultiPolygon * footprint()
Get the footprint of this shape (if available).
Provides access to sequential ASCII stream I/O.
This represents a shape in a project-based GUI interface.
bool toBool(const QString &string)
Global function to convert from a string to a boolean.
QString id() const
Get a unique, identifying string associated with this image.
void PutLine(const QString &line)
Writes string to file and appends a 'newline' string.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
Contains Pvl Groups and Pvl Objects.
Manage a stack of content handlers for reading XML files.
QString fileName() const
Get the file name of the cube that this image represents.