1#include "ImageFileListWidget.h" 
    7#include <QContextMenuEvent> 
   10#include <QInputDialog> 
   21#include <QXmlStreamWriter> 
   25#include "IException.h" 
   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";
 
  128        if (pvl.hasKeyword(key.
ToQt())) {
 
  139        col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
 
  143      m_tree->sortItems(pvl[
"SortColumn"], Qt::AscendingOrder);
 
  145      QList<QTreeWidgetItem *> allCubes;
 
  148      while (
m_tree->topLevelItemCount() > 0) {
 
  150        allCubes.append(group->takeChildren());
 
  157      for (
int cubeGrp = 0; cubeGrp < pvl.objects(); cubeGrp ++) {
 
  162        if (cubes.hasKeyword(
"Expanded")) {
 
  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();
 
 
  251    QList<QAction *> exportActs;
 
  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;
 
 
  348    QList<QTreeWidgetItem *> selected = 
m_tree->selectedItems();
 
  354    QList<QTreeWidgetItem *> groups;
 
  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) {
 
  512          file.PutLine(cubeItem->image()->fileName());
 
 
  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();
 
 
  559    QMap<QString, QVariant> states = expandedStates.toMap();
 
  561    if (states.contains(
"Expanded")) {
 
  562      item->setExpanded(states[
"Expanded"].
toBool());
 
  565      item->setExpanded(
true);
 
  568    QList<QVariant> childrenStates = states[
"Children"].toList();
 
  571    while (i < item->childCount() && i < childrenStates.count()) {
 
  576    while (i < item->childCount()) {
 
 
  590    QMap<QString, QVariant> result;
 
  592    result[
"Expanded"] = item->isExpanded();
 
  594    if (item->childCount()) {
 
  595      QList<QVariant> childrenStates;
 
  597      for (
int i = 0; i < item->childCount(); i++) {
 
  601      result[
"Children"] = childrenStates;
 
 
  614    xmlReader->pushContentHandler(
new XmlHandler(
this));
 
 
  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);
 
File name manipulation and expansion.
 
@ Io
A type of error that occurred when performing an actual I/O operation.
 
Adds specific functionality to C++ strings.
 
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"...
 
QString ToQt() const
Retuns the object string as a QString.
 
This represents a cube in a project-based GUI interface.
 
QString id() const
Get a unique, identifying string associated with this image.
 
Internalizes a list of images and allows for operations on the entire list.
 
QString name() const
Get the human-readable name of this image list.
 
The main project for ipce.
 
A single keyword-value pair.
 
bool isNamed(QString name) const
Determines whether two PvlKeywords have the same name or not.
 
Contains Pvl Groups and Pvl Objects.
 
PvlObject & object(const int index)
Return the object at the specified index.
 
This represents a shape in a project-based GUI interface.
 
Cube * cube()
Get the Cube * associated with this display property.
 
geos::geom::MultiPolygon * footprint()
Get the footprint of this shape (if available).
 
Provides access to sequential ASCII stream I/O.
 
Manage a stack of content handlers for reading XML files.
 
This is free and unencumbered software released into the public domain.
 
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
 
bool toBool(const QString &string)
Global function to convert from a string to a boolean.