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>
23 #include "Directory.h"
25 #include "IException.h"
27 #include "ImageTreeWidget.h"
28 #include "ImageTreeWidgetItem.h"
30 #include "ProgressBar.h"
32 #include "PvlObject.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);
174 "list widget settings from Pvl", _FILEINFO_);
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);