void ImportOptionsDlg::setCurrentDataset(ImportDescriptor* pImportDescriptor)
{
   if (pImportDescriptor == NULL)
   {
      return;
   }

   if (pImportDescriptor == mpCurrentDataset)
   {
      return;
   }

   // Apply changes to the current data set if necessary
   bool bSuccess = true;
   if ((mpCurrentDataset != NULL) && (mEditDataDescriptorModified == true))
   {
      if (mPromptForChanges == true)
      {
         int iReturn = QMessageBox::question(this, APP_NAME, "Apply changes to data?",
            QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::Cancel);
         if ((iReturn == QMessageBox::Yes) || (iReturn == QMessageBox::YesToAll))
         {
            bSuccess = applyChanges();
            if (iReturn == QMessageBox::YesToAll)
            {
               mPromptForChanges = false;
            }
         }
         else if (iReturn == QMessageBox::No)
         {
            // Update the validation icon for the original data descriptor
            validateDataset(mpCurrentDataset->getDataDescriptor());
         }
         else if (iReturn == QMessageBox::Cancel)
         {
            bSuccess = false;
         }
      }
      else
      {
         bSuccess = applyChanges();
      }
   }

   if (bSuccess == false)
   {
      // Select the tree widget item for the previously selected data set
      selectCurrentDatasetItem();
      return;
   }

   mpCurrentDataset = pImportDescriptor;

   // Destroy the existing edit data descriptor if necessary
   Service<ModelServices> pModel;
   if (mpEditDescriptor != NULL)
   {
      Classification* pClassification = mpEditDescriptor->getClassification();
      if (pClassification != NULL)
      {
         VERIFYNR(pClassification->detach(SIGNAL_NAME(Subject, Modified),
            Slot(this, &ImportOptionsDlg::editClassificationModified)));
      }

      RasterDataDescriptor* pRasterDescriptor = dynamic_cast<RasterDataDescriptor*>(mpEditDescriptor);
      if (pRasterDescriptor != NULL)
      {
         VERIFYNR(pRasterDescriptor->detach(SIGNAL_NAME(RasterDataDescriptor, RowsChanged),
            Slot(this, &ImportOptionsDlg::editDataDescriptorRowsModified)));
         VERIFYNR(pRasterDescriptor->detach(SIGNAL_NAME(RasterDataDescriptor, ColumnsChanged),
            Slot(this, &ImportOptionsDlg::editDataDescriptorColumnsModified)));
         VERIFYNR(pRasterDescriptor->detach(SIGNAL_NAME(RasterDataDescriptor, BandsChanged),
            Slot(this, &ImportOptionsDlg::editDataDescriptorBandsModified)));
      }

      RasterFileDescriptor* pRasterFileDescriptor =
         dynamic_cast<RasterFileDescriptor*>(mpEditDescriptor->getFileDescriptor());
      if (pRasterFileDescriptor != NULL)
      {
         VERIFYNR(pRasterFileDescriptor->detach(SIGNAL_NAME(RasterFileDescriptor, RowsChanged),
            Slot(this, &ImportOptionsDlg::editFileDescriptorRowsModified)));
         VERIFYNR(pRasterFileDescriptor->detach(SIGNAL_NAME(RasterFileDescriptor, ColumnsChanged),
            Slot(this, &ImportOptionsDlg::editFileDescriptorColumnsModified)));
         VERIFYNR(pRasterFileDescriptor->detach(SIGNAL_NAME(RasterFileDescriptor, BandsChanged),
            Slot(this, &ImportOptionsDlg::editFileDescriptorBandsModified)));
      }

      VERIFYNR(mpEditDescriptor->detach(SIGNAL_NAME(Subject, Modified),
         Slot(this, &ImportOptionsDlg::editDataDescriptorModified)));
      pModel->destroyDataDescriptor(mpEditDescriptor);
      mpEditDescriptor = NULL;
      mEditDataDescriptorModified = false;
   }

   // Create a new data descriptor to validate the user inputs
   DataDescriptor* pDescriptor = mpCurrentDataset->getDataDescriptor();
   if (pDescriptor != NULL)
   {
      mpEditDescriptor = pDescriptor->copy();
   }

   VERIFYNRV(mpEditDescriptor != NULL);
   VERIFYNR(mpEditDescriptor->attach(SIGNAL_NAME(Subject, Modified),
      Slot(this, &ImportOptionsDlg::editDataDescriptorModified)));

   RasterDataDescriptor* pRasterDescriptor = dynamic_cast<RasterDataDescriptor*>(mpEditDescriptor);
   FileDescriptor* pFileDescriptor = mpEditDescriptor->getFileDescriptor();
   RasterFileDescriptor* pRasterFileDescriptor = dynamic_cast<RasterFileDescriptor*>(pFileDescriptor);

   if (pRasterDescriptor != NULL)
   {
      VERIFYNR(pRasterDescriptor->attach(SIGNAL_NAME(RasterDataDescriptor, RowsChanged),
         Slot(this, &ImportOptionsDlg::editDataDescriptorRowsModified)));
      VERIFYNR(pRasterDescriptor->attach(SIGNAL_NAME(RasterDataDescriptor, ColumnsChanged),
         Slot(this, &ImportOptionsDlg::editDataDescriptorColumnsModified)));
      VERIFYNR(pRasterDescriptor->attach(SIGNAL_NAME(RasterDataDescriptor, BandsChanged),
         Slot(this, &ImportOptionsDlg::editDataDescriptorBandsModified)));
   }

   if (pRasterFileDescriptor != NULL)
   {
      VERIFYNR(pRasterFileDescriptor->attach(SIGNAL_NAME(RasterFileDescriptor, RowsChanged),
         Slot(this, &ImportOptionsDlg::editFileDescriptorRowsModified)));
      VERIFYNR(pRasterFileDescriptor->attach(SIGNAL_NAME(RasterFileDescriptor, ColumnsChanged),
         Slot(this, &ImportOptionsDlg::editFileDescriptorColumnsModified)));
      VERIFYNR(pRasterFileDescriptor->attach(SIGNAL_NAME(RasterFileDescriptor, BandsChanged),
         Slot(this, &ImportOptionsDlg::editFileDescriptorBandsModified)));
   }

   // Select the tree widget item for the current data set
   selectCurrentDatasetItem();

   // Disconnect pages
   updateConnections(false);

   // Subset page
   if (pRasterFileDescriptor != NULL)
   {
      // Show the tab if necessary
      if (mpTabWidget->indexOf(mpSubsetPage) == -1)
      {
         mpTabWidget->insertTab(2, mpSubsetPage, "Subset");
      }

      // Rows
      const vector<DimensionDescriptor>& rows = pRasterFileDescriptor->getRows();
      const vector<DimensionDescriptor>& loadedRows = pRasterDescriptor->getRows();
      mpSubsetPage->setRows(rows, loadedRows);

      // Columns
      const vector<DimensionDescriptor>& columns = pRasterFileDescriptor->getColumns();
      const vector<DimensionDescriptor>& loadedColumns = pRasterDescriptor->getColumns();
      mpSubsetPage->setColumns(columns, loadedColumns);

      // Bands
      const vector<DimensionDescriptor>& bands = pRasterFileDescriptor->getBands();
      const vector<DimensionDescriptor>& selectedBands = pRasterDescriptor->getBands();
      setSubsetBands(bands, selectedBands);

      // Initial bad band file directory
      if (pFileDescriptor != NULL)
      {
         QString strDirectory;

         string filename = pFileDescriptor->getFilename();
         if (filename.empty() == false)
         {
            QFileInfo fileInfo(QString::fromStdString(filename));
            strDirectory = fileInfo.absolutePath();
         }

         mpSubsetPage->setBadBandFileDirectory(strDirectory);
      }
   }
   else
   {
      // Remove the subset page, since the file descriptor either isn't
      // present or isn't a RasterFileDescriptor, just a FileDescriptor
      int index = mpTabWidget->indexOf(mpSubsetPage);
      if (index != -1)
      {
         mpTabWidget->removeTab(index);
      }
   }

   // Data descriptor page - enable editing for all fields
   mpDataPage->setDataDescriptor(mpEditDescriptor, true);

   // File descriptor page
   bool editFilePage = false;
   if (pRasterFileDescriptor != NULL)
   {
      unsigned int numRows = pRasterFileDescriptor->getRowCount();
      unsigned int numColumns = pRasterFileDescriptor->getColumnCount();
      unsigned int bitsPerElement = pRasterFileDescriptor->getBitsPerElement();
      unsigned int numBands = pRasterFileDescriptor->getBandCount();
      if ((numRows == 0) || (numColumns == 0) || (numBands == 0) || (bitsPerElement == 0))
      {
         editFilePage = true;
      }
   }

   mpFilePage->setFileDescriptor(pFileDescriptor, editFilePage);

   int iIndex = mpTabWidget->indexOf(mpFilePage);
   if (iIndex != -1)
   {
      if (pFileDescriptor == NULL)
      {
         mpTabWidget->removeTab(iIndex);
      }
   }
   else
   {
      if (pFileDescriptor != NULL)
      {
         mpTabWidget->insertTab(1, mpFilePage, "File");
      }
   }

   // Classification page
   updateClassificationLabel();

   Classification* pClassification = mpEditDescriptor->getClassification();
   if (pClassification != NULL)
   {
      VERIFYNR(pClassification->attach(SIGNAL_NAME(Subject, Modified),
         Slot(this, &ImportOptionsDlg::editClassificationModified)));
      mpClassificationPage->setClassification(pClassification);
   }

   // Metadata page
   mpMetadataPage->setMetadata(mpEditDescriptor->getMetadata());

   // Wavelengths page
   bool bWavelengthsPageActive = false;
   if (mpTabWidget->currentWidget() == mpWavelengthsPage)
   {
      bWavelengthsPageActive = true;
   }

   int index = mpTabWidget->indexOf(mpWavelengthsPage);
   if (index != -1)
   {
      mpTabWidget->removeTab(index);
   }

   if (pRasterFileDescriptor != NULL)
   {
      // Populate the wavelengths with the file descriptor bands since the metadata wavelengths
      // apply to all bands in the file
      mpWavelengthsPage->setWavelengths(pRasterFileDescriptor->getBands(), mpEditDescriptor->getMetadata());

      if (pRasterDescriptor != NULL)
      {
         mpWavelengthsPage->highlightActiveBands(pRasterDescriptor->getBands());
      }

      mpTabWidget->addTab(mpWavelengthsPage, "Wavelengths");

      if (bWavelengthsPageActive == true)
      {
         mpTabWidget->setCurrentWidget(mpWavelengthsPage);
      }
   }

   // Importer page
   bool bImporterPageActive = false;
   if (mpImporterPage != NULL)
   {
      if (mpTabWidget->currentWidget() == mpImporterPage)
      {
         bImporterPageActive = true;
      }
   }

   removeImporterPage();

   if (mpImporter != NULL)
   {
      mpImporterPage = mpImporter->getImportOptionsWidget(mpEditDescriptor);
      if (mpImporterPage != NULL)
      {
         QLayout* pLayout = mpImporterPage->layout();
         if (pLayout != NULL)
         {
            if (pLayout->margin() <= 0)
            {
               pLayout->setMargin(10);
            }
         }

         QString strCaption = mpImporterPage->windowTitle();
         if (strCaption.isEmpty() == true)
         {
            strCaption = "Importer";
         }

         mpTabWidget->addTab(mpImporterPage, strCaption);

         if (bImporterPageActive == true)
         {
            mpTabWidget->setCurrentWidget(mpImporterPage);
         }
      }

      // Set the valid processing locations on the data page.  This must be done after getting the import options
      // widget from the importer so that the auto importer will correctly query the importer that is used.
      // This can be changed if the importer design (and auto importer) is modified to support valid processing
      // locations for a specific data set.
      vector<ProcessingLocation> locations;
      if (mpImporter->isProcessingLocationSupported(IN_MEMORY) == true)
      {
         locations.push_back(IN_MEMORY);
      }

      if (mpImporter->isProcessingLocationSupported(ON_DISK) == true)
      {
         locations.push_back(ON_DISK);
      }

      if (mpImporter->isProcessingLocationSupported(ON_DISK_READ_ONLY) == true)
      {
         locations.push_back(ON_DISK_READ_ONLY);
      }

      mpDataPage->setValidProcessingLocations(locations);
   }

   // Validate the current data descriptor
   validateEditDataset();

   // Reconnect the pages
   updateConnections(true);

   // Notify connected objects
   emit currentDatasetChanged(mpCurrentDataset);
}
ImportDescriptor* Nitf::NitfImporterShell::getImportDescriptor(const string& filename, ossim_uint32 imageSegment,
                                                               const Nitf::OssimFileResource& pFile,
                                                               const ossimNitfFileHeaderV2_X* pFileHeader,
                                                               const ossimNitfImageHeaderV2_X* pImageSubheader)
{
   if (pImageSubheader == NULL)
   {
      return NULL;
   }

   EncodingType dataType = ossimImageHeaderToEncodingType(pImageSubheader);
   if (dataType.isValid() == false)
   {
      return NULL;
   }

   stringstream imageNameStream;
   imageNameStream << "I" << imageSegment + 1;
   string imageName = imageNameStream.str();

   ImportDescriptorResource pImportDescriptor(filename + "-" + imageName,
      TypeConverter::toString<RasterElement>(), NULL);
   VERIFYRV(pImportDescriptor.get() != NULL, NULL);
   pImportDescriptor->setImported(pImageSubheader->getRepresentation() != "NODISPLY");

   RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor());
   VERIFYRV(pDescriptor != NULL, NULL);

   vector<DimensionDescriptor> bands =  RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfBands(),
      true, false, true);
   pDescriptor->setBands(bands);

   vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfRows(),
      true, false, true);
   pDescriptor->setRows(rows);

   vector<DimensionDescriptor> cols = RasterUtilities::generateDimensionVector(pImageSubheader->getNumberOfCols(),
      true, false, true);
   pDescriptor->setColumns(cols);

   if (pImageSubheader->getIMode() == "P")
   {
      pDescriptor->setInterleaveFormat(BIP);
   }
   else if (pImageSubheader->getIMode() == "R")
   {
      pDescriptor->setInterleaveFormat(BIL);
   }
   else
   {
      pDescriptor->setInterleaveFormat(BSQ);
   }

   pDescriptor->setDataType(dataType);
   pDescriptor->setValidDataTypes(vector<EncodingType>(1, dataType));
   pDescriptor->setProcessingLocation(IN_MEMORY);

   map<string, TrePlugInResource> parsers;
   string errorMessage;

   // Set the file descriptor
   RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(
      RasterUtilities::generateAndSetFileDescriptor(pDescriptor, filename, imageName, LITTLE_ENDIAN_ORDER));
   if (pFileDescriptor == NULL)
   {
      return NULL;
   }

   // Set the bits per element, which may be different than the data type in the data descriptor,
   // using NBPP instead of ABPP as is done in ossimNitfTileSource.cpp.
   unsigned int bitsPerPixel = static_cast<unsigned int>(pImageSubheader->getBitsPerPixelPerBand());
   pFileDescriptor->setBitsPerElement(bitsPerPixel);

   // Populate the metadata and set applicable values in the data descriptor
   if (Nitf::importMetadata(imageSegment + 1, pFile, pFileHeader, pImageSubheader, pDescriptor, parsers,
      errorMessage) == true)
   {
      // Populate specific fields in the data descriptor or file descriptor from the TREs
      const DynamicObject* pMetadata = pDescriptor->getMetadata();
      VERIFYRV(pMetadata, NULL);

      // Pixel size - This info is contained in multiple TREs, but there is no documentation on which
      // TRE contains the more precise value if multiple TREs containing the info are present.  Choosing
      // the order ACFTA, BANDSA, ACFTB, and BANDSB where the later "B" TREs will overwrite the values
      // contained in the earlier "A" TREs.  The BANDSB TRE contains GSD values for each band, which is
      // currently not supported, so only set the pixel size if the values in all bands are the same.
      double xGsd = 1.0;
      double yGsd = 1.0;

      const string acrftaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "ACFTA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pAcrftA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(acrftaPath));
      if (pAcrftA != NULL)
      {
         // The ACFTA spec calls out specific spacing units for "SAR" and "EO-IR" data, but does not indicate how
         // this is determined.  It seems to be related to the ACFTB SENSOR_ID_TYPE field, but that field is not
         // present in the ACFTA TRE.  So just check for "SAR" data from the ICAT field in the image subheader
         // and assume every other data type is "EO-IR" data.
         const string imageCategory = pImageSubheader->getCategory().trim();

         const DataVariant& rowSpacing = pAcrftA->getAttribute(Nitf::TRE::ACFTA::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            if (imageCategory == "SAR")
            {
               yGsd = getGsd(rowSpacing, "f");     // Feet
            }
            else
            {
               yGsd = getGsd(rowSpacing, "r");     // Micro-radians
            }
         }

         const DataVariant& columnSpacing = pAcrftA->getAttribute(Nitf::TRE::ACFTA::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            if (imageCategory == "SAR")
            {
               xGsd = getGsd(columnSpacing, "f");  // Feet
            }
            else
            {
               xGsd = getGsd(columnSpacing, "r");  // Micro-radians
            }
         }
      }

      const string bandsaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BANDSA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBandsA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(bandsaPath));
      if (pBandsA != NULL)
      {
         const DataVariant& rowSpacing = pBandsA->getAttribute(Nitf::TRE::BANDSA::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            const DataVariant& rowSpacingUnits = pBandsA->getAttribute(Nitf::TRE::BANDSA::ROW_SPACING_UNITS);
            if (rowSpacingUnits.isValid() == true)
            {
               yGsd = getGsd(rowSpacing, rowSpacingUnits.toXmlString());
            }
         }

         const DataVariant& columnSpacing = pBandsA->getAttribute(Nitf::TRE::BANDSA::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            const DataVariant& columnSpacingUnits = pBandsA->getAttribute(Nitf::TRE::BANDSA::COL_SPACING_UNITS);
            if (columnSpacingUnits.isValid() == true)
            {
               xGsd = getGsd(columnSpacing, columnSpacingUnits.toXmlString());
            }
         }
      }

      const string acrftbPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "ACFTB",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pAcrftB = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(acrftbPath));
      if (pAcrftB != NULL)
      {
         const DataVariant& rowSpacing = pAcrftB->getAttribute(Nitf::TRE::ACFTB::ROW_SPACING);
         if (rowSpacing.isValid() == true)
         {
            const DataVariant& rowSpacingUnits = pAcrftB->getAttribute(Nitf::TRE::ACFTB::ROW_SPACING_UNITS);
            if (rowSpacingUnits.isValid() == true)
            {
               yGsd = getGsd(rowSpacing, rowSpacingUnits.toXmlString());
            }
         }

         const DataVariant& columnSpacing = pAcrftB->getAttribute(Nitf::TRE::ACFTB::COL_SPACING);
         if (columnSpacing.isValid() == true)
         {
            const DataVariant& columnSpacingUnits = pAcrftB->getAttribute(Nitf::TRE::ACFTB::COL_SPACING_UNITS);
            if (columnSpacingUnits.isValid() == true)
            {
               xGsd = getGsd(columnSpacing, columnSpacingUnits.toXmlString());
            }
         }
      }

      const string bandsbPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BANDSB",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBandsB = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(bandsbPath));
      if (pBandsB != NULL)
      {
         bool validRowGsd = false;

         const DataVariant& rowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD);
         if (rowGsd.isValid() == true)
         {
            const DataVariant& rowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD_UNIT);
            if (rowGsdUnits.isValid() == true)
            {
               yGsd = getGsd(rowGsd, rowGsdUnits.toXmlString());
               validRowGsd = true;
            }
         }

         if (validRowGsd == false)
         {
            if (pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD + "#0").isValid())
            {
               double commonYGsd = -1.0;

               unsigned int numBands = pDescriptor->getBandCount();
               for (unsigned int i = 0; i < numBands; ++i)
               {
                  double bandYGsd = -1.0;
                  string bandPostfix = "#" + StringUtilities::toDisplayString(i);

                  const DataVariant& bandRowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD + bandPostfix);
                  if (bandRowGsd.isValid() == true)
                  {
                     const DataVariant& bandRowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::ROW_GSD_UNIT +
                        bandPostfix);
                     if (bandRowGsdUnits.isValid() == true)
                     {
                        bandYGsd = getGsd(bandRowGsd, bandRowGsdUnits.toXmlString());
                     }
                  }

                  if (bandYGsd == commonYGsd)
                  {
                     continue;
                  }

                  if (commonYGsd != -1.0)
                  {
                     commonYGsd = -1.0;
                     break;
                  }

                  commonYGsd = bandYGsd;
               }

               if (commonYGsd != 1.0)
               {
                  yGsd = commonYGsd;
               }
            }
         }

         bool validColumnGsd = false;

         const DataVariant& columnGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD);
         if (columnGsd.isValid() == true)
         {
            const DataVariant& columnGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD_UNITS);
            if (columnGsdUnits.isValid() == true)
            {
               xGsd = getGsd(columnGsd, columnGsdUnits.toXmlString());
               validColumnGsd = true;
            }
         }

         if (validColumnGsd == false)
         {
            if (pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD + "#0").isValid())
            {
               double commonXGsd = -1.0;

               unsigned int numBands = pDescriptor->getBandCount();
               for (unsigned int i = 0; i < numBands; ++i)
               {
                  double bandXGsd = -1.0;
                  string bandPostfix = "#" + StringUtilities::toDisplayString(i);

                  const DataVariant& bandRowGsd = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD + bandPostfix);
                  if (bandRowGsd.isValid() == true)
                  {
                     const DataVariant& bandRowGsdUnits = pBandsB->getAttribute(Nitf::TRE::BANDSB::COL_GSD_UNIT +
                        bandPostfix);
                     if (bandRowGsdUnits.isValid() == true)
                     {
                        bandXGsd = getGsd(bandRowGsd, bandRowGsdUnits.toXmlString());
                     }
                  }

                  if (bandXGsd == commonXGsd)
                  {
                     continue;
                  }

                  if (commonXGsd != -1.0)
                  {
                     commonXGsd = -1.0;
                     break;
                  }

                  commonXGsd = bandXGsd;
               }

               if (commonXGsd != 1.0)
               {
                  xGsd = commonXGsd;
               }
            }
         }
      }

      double magFactor = 1.0;
      ossimString imag = pImageSubheader->getImageMagnification().trim();
      if (imag.empty() == false)
      {
         // Need to multiply the GSD values by the image magnification (IMAG) value in the image subheader
         if (imag[0] == '/')
         {
            ossimString reciprocal = imag.substr(1);
            magFactor = 1.0 / reciprocal.toDouble();
         }
         else
         {
            magFactor = imag.toDouble();
         }

         xGsd *= magFactor;
         yGsd *= magFactor;
      }

      pDescriptor->setXPixelSize(xGsd);
      pDescriptor->setYPixelSize(yGsd);

      // Higher precision GCPs
      const string blockaPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::TRE_METADATA,
         "BLOCKA",
         "0",
         END_METADATA_NAME
      };

      const DynamicObject* pBlockA = dv_cast<DynamicObject>(&pMetadata->getAttributeByPath(blockaPath));
      if (pBlockA != NULL)
      {
         const DataVariant& blockLines = pBlockA->getAttribute(Nitf::TRE::BLOCKA::L_LINES);
         if (blockLines.isValid() == true)
         {
            unsigned int numBlockRows = 0;
            if (blockLines.getValue<unsigned int>(numBlockRows) == true)
            {
               // Need to multiply the number of rows by the image magnification (IMAG) value in the image subheader
               numBlockRows = static_cast<unsigned int>(static_cast<double>(numBlockRows) * magFactor);
               if (numBlockRows == pFileDescriptor->getRowCount())
               {
                  list<GcpPoint> updatedGcps;

                  list<GcpPoint> gcps = pFileDescriptor->getGcps();
                  for (list<GcpPoint>::iterator iter = gcps.begin(); iter != gcps.end(); ++iter)
                  {
                     GcpPoint gcp = *iter;
                     string coordinateText;

                     list<GcpPoint>::size_type index = updatedGcps.size();
                     if (index == 0)
                     {
                        const DataVariant& gcp1 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::FRFC_LOC);
                        if (gcp1.isValid() == true)
                        {
                           coordinateText = gcp1.toXmlString();
                        }
                     }
                     else if (index == 1)
                     {
                        const DataVariant& gcp2 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::FRLC_LOC);
                        if (gcp2.isValid() == true)
                        {
                           coordinateText = gcp2.toXmlString();
                        }
                     }
                     else if (index == 2)
                     {
                        const DataVariant& gcp3 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::LRLC_LOC);
                        if (gcp3.isValid() == true)
                        {
                           coordinateText = gcp3.toXmlString();
                        }
                     }
                     else if (index == 3)
                     {
                        const DataVariant& gcp4 = pBlockA->getAttribute(Nitf::TRE::BLOCKA::LRFC_LOC);
                        if (gcp4.isValid() == true)
                        {
                           coordinateText = gcp4.toXmlString();
                        }
                     }

                     if (StringUtilities::isAllBlank(coordinateText) == false)
                     {
                        coordinateText.insert(10, ", ");
                        LatLonPoint latLon(coordinateText);
                        gcp.mCoordinate = latLon.getCoordinates();
                     }

                     updatedGcps.push_back(gcp);
                  }

                  pFileDescriptor->setGcps(updatedGcps);
               }
            }
         }
      }

      // This only checks the first BANDSB. It is possible to have multiple BANDSB TREs.
      // If someone runs across real data where the bad band info is in another BANDSB TRE
      // this code will need to be modified.
      if (pBandsB != NULL && pBandsB->getAttribute(Nitf::TRE::BANDSB::BAD_BAND + "#0").isValid())
      {
         const vector<DimensionDescriptor>& curBands = pDescriptor->getBands();
         vector<DimensionDescriptor> newBands;
         for (size_t idx = 0; idx < curBands.size(); ++idx)
         {
            const int* pVal = dv_cast<int>(&pBandsB->getAttribute(
               Nitf::TRE::BANDSB::BAD_BAND + "#" + StringUtilities::toDisplayString(idx)));
            if (pVal == NULL || *pVal == 1) // 0 == invalid or suspect band, 1 = valid band
            {
               newBands.push_back(curBands[idx]);
            }
         }
         pDescriptor->setBands(newBands);
      }

      // Bad values
      if (pImageSubheader->hasTransparentCode() == true)
      {
         vector<int> badValues;
         badValues.push_back(static_cast<int>(pImageSubheader->getTransparentCode()));
         pDescriptor->setBadValues(badValues);
      }

      // If red, green, OR blue bands are valid, set the display mode to RGB.
      if (pDescriptor->getDisplayBand(RED).isValid() == true ||
         pDescriptor->getDisplayBand(GREEN).isValid() == true ||
         pDescriptor->getDisplayBand(BLUE).isValid() == true)
      {
         pDescriptor->setDisplayMode(RGB_MODE);
      }
      // Otherwise, if the gray band is valid, set the display mode to GRAYSCALE.
      else if (pDescriptor->getDisplayBand(GRAY).isValid() == true)
      {
         pDescriptor->setDisplayMode(GRAYSCALE_MODE);
      }
      // Otherwise, if at least 3 bands are available, set the display mode to RGB,
      // and set the first three bands to red, green, and blue respectively.
      else if (bands.size() >= 3)
      {
         pDescriptor->setDisplayBand(RED, bands[0]);
         pDescriptor->setDisplayBand(GREEN, bands[1]);
         pDescriptor->setDisplayBand(BLUE, bands[2]);
         pDescriptor->setDisplayMode(RGB_MODE);
      }
      // Otherwise, if at least 1 band is available, set the display mode to GRAYSCALE,
      // and set the first band to GRAY.
      else if (bands.empty() == false)
      {
         pDescriptor->setDisplayBand(GRAY, bands[0]);
         pDescriptor->setDisplayMode(GRAYSCALE_MODE);
      }
      else
      {
         return NULL;
      }

      // Special initialization for J2K compressed image segments
      const string compressionPath[] =
      {
         Nitf::NITF_METADATA,
         Nitf::IMAGE_SUBHEADER,
         Nitf::ImageSubheaderFieldNames::COMPRESSION,
         END_METADATA_NAME
      };

      string imageCompression = pMetadata->getAttributeByPath(compressionPath).toDisplayString();
      if ((imageCompression == Nitf::ImageSubheaderFieldValues::IC_C8) ||
         (imageCompression == Nitf::ImageSubheaderFieldValues::IC_M8))
      {
         // Per Section 8.1 of the BIIF Profile for JPEG 2000 Version 01.10 (BPJ2K01.10),
         // if the values in the J2K data differ from the values in the image subheader,
         // the J2K values are given precedence.
         opj_image_t* pImage = getImageInfo(filename, imageSegment, OPJ_CODEC_J2K);
         if (pImage == NULL)
         {
            pImage = getImageInfo(filename, imageSegment, OPJ_CODEC_JP2);
         }

         if (pImage != NULL)
         {
            // Bits per element
            unsigned int bitsPerElement = pImage->comps->prec;
            if (bitsPerElement != pFileDescriptor->getBitsPerElement())
            {
               pFileDescriptor->setBitsPerElement(bitsPerElement);
            }

            // Data type
            EncodingType dataType = INT1UBYTE;
            if (bitsPerElement <= 8)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT1SBYTE;
               }
               else
               {
                  dataType = INT1UBYTE;
               }
            }
            else if (bitsPerElement <= 16)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT2SBYTES;
               }
               else
               {
                  dataType = INT2UBYTES;
               }
            }
            else if (bitsPerElement <= 32)
            {
               if (pImage->comps->sgnd)
               {
                  dataType = INT4SBYTES;
               }
               else
               {
                  dataType = INT4UBYTES;
               }
            }
            else if (bitsPerElement <= 64)
            {
               dataType = FLT8BYTES;
            }

            if (dataType != pDescriptor->getDataType())
            {
               pDescriptor->setDataType(dataType);
            }

            // Rows
            unsigned int numRows = pImage->comps->h;
            if (numRows != pFileDescriptor->getRowCount())
            {
               vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(numRows, true, false, true);
               pDescriptor->setRows(rows);
               pFileDescriptor->setRows(rows);
            }

            // Columns
            unsigned int numColumns = pImage->comps->w;
            if (numColumns != pFileDescriptor->getColumnCount())
            {
               vector<DimensionDescriptor> columns = RasterUtilities::generateDimensionVector(numColumns, true, false,
                  true);
               pDescriptor->setColumns(columns);
               pFileDescriptor->setColumns(columns);
            }

            // Bands
            unsigned int numBands = pImage->numcomps;
            if (numBands != pFileDescriptor->getBandCount())
            {
               vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector(numBands, true, false,
                  true);
               pDescriptor->setBands(bands);
               pFileDescriptor->setBands(bands);
            }

            // Cleanup
            opj_image_destroy(pImage);
         }

         // Set the interleave format as BIP, which is the interleave format for J2K data
         pDescriptor->setInterleaveFormat(BIP);
         pFileDescriptor->setInterleaveFormat(BIP);
      }

      mParseMessages[imageSegment] = errorMessage;
   }

   return pImportDescriptor.release();
}
void FileDescriptorWidget::initialize()
{
   mpTreeWidget->clear();
   mpGcpTree->clear();
   mpGcpGroup->hide();

   if (mpFileDescriptor == NULL)
   {
      return;
   }

   // Filename
   QTreeWidgetItem* pFilenameItem = new QTreeWidgetItem(mpTreeWidget);
   if (pFilenameItem != NULL)
   {
      string filename = mpFileDescriptor->getFilename();

      pFilenameItem->setText(0, "Filename");
      pFilenameItem->setText(1, QString::fromStdString(filename));
   }

   // Data set location
   QTreeWidgetItem* pDatasetLocationItem = new QTreeWidgetItem(mpTreeWidget);
   if (pDatasetLocationItem != NULL)
   {
      string datasetLocation = mpFileDescriptor->getDatasetLocation();

      pDatasetLocationItem->setText(0, "Data Set Location");
      pDatasetLocationItem->setText(1, QString::fromStdString(datasetLocation));
   }

   // Endian
   QTreeWidgetItem* pEndianItem = new QTreeWidgetItem(mpTreeWidget);
   if (pEndianItem != NULL)
   {
      EndianType endian = mpFileDescriptor->getEndian();
      string endianText = StringUtilities::toDisplayString(endian);

      pEndianItem->setText(0, "Endian");
      pEndianItem->setText(1, QString::fromStdString(endianText));

      if (mReadOnly == false)
      {
         QComboBox* pEndianCombo = new QComboBox(mpTreeWidget);
         pEndianCombo->setEditable(false);
         pEndianCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(LITTLE_ENDIAN_ORDER)));
         pEndianCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(BIG_ENDIAN_ORDER)));
         pEndianCombo->hide();

         mpTreeWidget->setCellWidgetType(pEndianItem, 1, CustomTreeWidget::COMBO_BOX);
         mpTreeWidget->setComboBox(pEndianItem, 1, pEndianCombo);
      }
   }

   // Raster element file descriptor items
   RasterFileDescriptor* pRasterDescriptor = dynamic_cast<RasterFileDescriptor*>(mpFileDescriptor);
   if (pRasterDescriptor == NULL)
   {
      return;
   }

   mpGcpGroup->show();

   // Rows
   QTreeWidgetItem* pRowsItem = new QTreeWidgetItem();
   if (pRowsItem != NULL)
   {
      unsigned int rows = pRasterDescriptor->getRowCount();

      pRowsItem->setText(0, "Rows");
      pRowsItem->setText(1, QString::number(rows));

      mpTreeWidget->insertTopLevelItem(2, pRowsItem);
      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pRowsItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Columns
   QTreeWidgetItem* pColumnsItem = new QTreeWidgetItem();
   if (pColumnsItem != NULL)
   {
      unsigned int columns = pRasterDescriptor->getColumnCount();

      pColumnsItem->setText(0, "Columns");
      pColumnsItem->setText(1, QString::number(columns));

      mpTreeWidget->insertTopLevelItem(3, pColumnsItem);
      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pColumnsItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Bits per element
   QTreeWidgetItem* pBitsPerElementItem = new QTreeWidgetItem();
   if (pBitsPerElementItem != NULL)
   {
      unsigned int bitsPerElement = pRasterDescriptor->getBitsPerElement();

      pBitsPerElementItem->setText(0, "Bits Per Element");
      pBitsPerElementItem->setText(1, QString::number(bitsPerElement));

      mpTreeWidget->insertTopLevelItem(4, pBitsPerElementItem);
      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pBitsPerElementItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Header bytes
   QTreeWidgetItem* pHeaderBytesItem = new QTreeWidgetItem(mpTreeWidget);
   if (pHeaderBytesItem != NULL)
   {
      unsigned int headerBytes = pRasterDescriptor->getHeaderBytes();

      pHeaderBytesItem->setText(0, "Header Bytes");
      pHeaderBytesItem->setText(1, QString::number(headerBytes));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pHeaderBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Trailer bytes
   QTreeWidgetItem* pTrailerBytesItem = new QTreeWidgetItem(mpTreeWidget);
   if (pTrailerBytesItem != NULL)
   {
      unsigned int trailerBytes = pRasterDescriptor->getTrailerBytes();

      pTrailerBytesItem->setText(0, "Trailer Bytes");
      pTrailerBytesItem->setText(1, QString::number(trailerBytes));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pTrailerBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Preline bytes
   QTreeWidgetItem* pPrelineBytesItem = new QTreeWidgetItem(mpTreeWidget);
   if (pPrelineBytesItem != NULL)
   {
      unsigned int prelineBytes = pRasterDescriptor->getPrelineBytes();

      pPrelineBytesItem->setText(0, "Preline Bytes");
      pPrelineBytesItem->setText(1, QString::number(prelineBytes));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pPrelineBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Postline bytes
   QTreeWidgetItem* pPostlineBytesItem = new QTreeWidgetItem(mpTreeWidget);
   if (pPostlineBytesItem != NULL)
   {
      unsigned int postlineBytes = pRasterDescriptor->getPostlineBytes();

      pPostlineBytesItem->setText(0, "Postline Bytes");
      pPostlineBytesItem->setText(1, QString::number(postlineBytes));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pPostlineBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Pixel size
   QTreeWidgetItem* pXPixelSizeItem = new QTreeWidgetItem(mpTreeWidget);
   if (pXPixelSizeItem != NULL)
   {
      double pixelSize = pRasterDescriptor->getXPixelSize();

      pXPixelSizeItem->setText(0, "X Pixel Size");
      pXPixelSizeItem->setText(1, QString::number(pixelSize));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pXPixelSizeItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   QTreeWidgetItem* pYPixelSizeItem = new QTreeWidgetItem(mpTreeWidget);
   if (pYPixelSizeItem != NULL)
   {
      double pixelSize = pRasterDescriptor->getYPixelSize();

      pYPixelSizeItem->setText(0, "Y Pixel Size");
      pYPixelSizeItem->setText(1, QString::number(pixelSize));

      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pYPixelSizeItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Units
   const Units* pUnits = pRasterDescriptor->getUnits();
   if (pUnits != NULL)
   {
      QTreeWidgetItem* pUnitsItem = new QTreeWidgetItem(mpTreeWidget);
      if (pUnitsItem != NULL)
      {
         pUnitsItem->setText(0, "Units");
         pUnitsItem->setBackgroundColor(1, Qt::lightGray);

         // Name
         QTreeWidgetItem* pNameItem = new QTreeWidgetItem(pUnitsItem);
         if (pNameItem != NULL)
         {
            string unitsName = pUnits->getUnitName();

            pNameItem->setText(0, "Name");
            pNameItem->setText(1, QString::fromStdString(unitsName));

            if (mReadOnly == false)
            {
               mpTreeWidget->setCellWidgetType(pNameItem, 1, CustomTreeWidget::LINE_EDIT);
            }
         }

         // Type
         QTreeWidgetItem* pTypeItem = new QTreeWidgetItem(pUnitsItem);
         if (pTypeItem != NULL)
         {
            UnitType unitType = pUnits->getUnitType();
            string unitTypeText = StringUtilities::toDisplayString(unitType);

            pTypeItem->setText(0, "Type");
            pTypeItem->setText(1, QString::fromStdString(unitTypeText));

            if (mReadOnly == false)
            {
               QComboBox* pUnitTypeCombo = new QComboBox(mpTreeWidget);
               pUnitTypeCombo->setEditable(false);
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(ABSORBANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(ABSORPTANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(DIGITAL_NO)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(DISTANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(EMISSIVITY)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(RADIANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(REFLECTANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(REFLECTANCE_FACTOR)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(TRANSMITTANCE)));
               pUnitTypeCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(CUSTOM_UNIT)));
               pUnitTypeCombo->hide();

               mpTreeWidget->setCellWidgetType(pTypeItem, 1, CustomTreeWidget::COMBO_BOX);
               mpTreeWidget->setComboBox(pTypeItem, 1, pUnitTypeCombo);
            }
         }

         // Scale
         QTreeWidgetItem* pScaleItem = new QTreeWidgetItem(pUnitsItem);
         if (pScaleItem != NULL)
         {
            double dScale = pUnits->getScaleFromStandard();

            pScaleItem->setText(0, "Scale");
            pScaleItem->setText(1, QString::number(dScale));

            if (mReadOnly == false)
            {
               mpTreeWidget->setCellWidgetType(pScaleItem, 1, CustomTreeWidget::LINE_EDIT);
            }
         }

         // Range minimum
         QTreeWidgetItem* pMinimumItem = new QTreeWidgetItem(pUnitsItem);
         if (pMinimumItem != NULL)
         {
            double dMinimum = pUnits->getRangeMin();

            pMinimumItem->setText(0, "Range Minimum");
            pMinimumItem->setText(1, QString::number(dMinimum));

            if (mReadOnly == false)
            {
               mpTreeWidget->setCellWidgetType(pMinimumItem, 1, CustomTreeWidget::LINE_EDIT);
            }
         }

         // Range maximum
         QTreeWidgetItem* pMaximumItem = new QTreeWidgetItem(pUnitsItem);
         if (pMaximumItem != NULL)
         {
            double dMaximum = pUnits->getRangeMax();

            pMaximumItem->setText(0, "Range Maximum");
            pMaximumItem->setText(1, QString::number(dMaximum));

            if (mReadOnly == false)
            {
               mpTreeWidget->setCellWidgetType(pMaximumItem, 1, CustomTreeWidget::LINE_EDIT);
            }
         }
      }
   }

   // GCPs
   if (mpGcpTree != NULL)
   {
      const list<GcpPoint>& gcps = pRasterDescriptor->getGcps();
      if (gcps.empty() == false)
      {
         list<GcpPoint>::const_iterator iter;
         unsigned int i = 0;

         for (iter = gcps.begin(), i = 0; iter != gcps.end(); ++iter, ++i)
         {
            GcpPoint gcp = *iter;

            QTreeWidgetItem* pGcpItem = new QTreeWidgetItem(mpGcpTree);
            if (pGcpItem != NULL)
            {
               QString strLatitude;
               QString strLongitude;
               LatLonPoint latLonPoint(gcp.mCoordinate);

               string latText = latLonPoint.getLatitudeText();
               if (latText.empty() == false)
               {
                  strLatitude = QString::fromStdString(latText);
               }

               string longText = latLonPoint.getLongitudeText();
               if (longText.empty() == false)
               {
                  strLongitude = QString::fromStdString(longText);
               }

               pGcpItem->setText(0, QString("GCP ") + QString::number(i + 1));
               pGcpItem->setText(1, QString::number(gcp.mPixel.mX + 1.0));
               pGcpItem->setText(2, QString::number(gcp.mPixel.mY + 1.0));
               pGcpItem->setText(3, strLatitude);
               pGcpItem->setText(4, strLongitude);
            }
         }

         mpGcpTree->setEnabled(true);
      }
      else
      {
         mpGcpTree->setEnabled(false);
      }
   }

   // Bands
   QTreeWidgetItem* pBandsItem = new QTreeWidgetItem();
   if (pBandsItem != NULL)
   {
      unsigned int bands = pRasterDescriptor->getBandCount();

      pBandsItem->setText(0, "Bands");
      pBandsItem->setText(1, QString::number(bands));

      mpTreeWidget->insertTopLevelItem(4, pBandsItem);
      if (mReadOnly == false)
      {
         mpTreeWidget->setCellWidgetType(pBandsItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Interleave format
   InterleaveFormatType interleave = pRasterDescriptor->getInterleaveFormat();

   QTreeWidgetItem* pInterleaveItem = new QTreeWidgetItem();
   if (pInterleaveItem != NULL)
   {
      string interleaveText = StringUtilities::toDisplayString(interleave);
      if (interleave == BSQ)
      {
         const vector<const Filename*>& bandFiles = pRasterDescriptor->getBandFiles();
         if (bandFiles.size() > 0)
         {
            interleaveText += BSQ_MULTI_SUFFIX;
         }
         else
         {
            interleaveText += BSQ_SINGLE_SUFFIX;
         }
      }
      pInterleaveItem->setText(0, "Interleave Format");
      pInterleaveItem->setText(1, QString::fromStdString(interleaveText));

      mpTreeWidget->insertTopLevelItem(7, pInterleaveItem);
      if (mReadOnly == false)
      {
         QComboBox* pInterleaveCombo = new QComboBox(mpTreeWidget);
         pInterleaveCombo->setEditable(false);
         pInterleaveCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(BIL)));
         pInterleaveCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(BIP)));
         pInterleaveCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(BSQ) + BSQ_SINGLE_SUFFIX));
         pInterleaveCombo->addItem(QString::fromStdString(StringUtilities::toDisplayString(BSQ) + BSQ_MULTI_SUFFIX));
         pInterleaveCombo->hide();

         mpTreeWidget->setCellWidgetType(pInterleaveItem, 1, CustomTreeWidget::COMBO_BOX);
         mpTreeWidget->setComboBox(pInterleaveItem, 1, pInterleaveCombo);
      }
   }

   // Band files
   const vector<const Filename*>& bandFiles = pRasterDescriptor->getBandFiles();
   for (unsigned int i = 0; i < bandFiles.size(); ++i)
   {
      string bandFilename = bandFiles[i]->getFullPathAndName();
      if (bandFilename.empty() == false)
      {
         QTreeWidgetItem* pBandItem = new QTreeWidgetItem(pFilenameItem);
         if (pBandItem != NULL)
         {
            pBandItem->setText(0, QString::number(i + 1));
            pBandItem->setText(1, QString::fromStdString(bandFilename));

            if (mReadOnly == false)
            {
               mpTreeWidget->setCellWidgetType(pBandItem, 1, CustomTreeWidget::BROWSE_FILE_EDIT);
               mpTreeWidget->setFileBrowser(pBandItem, 1, mpFileBrowser);
            }
         }
      }
   }

   // Preband bytes
   QTreeWidgetItem* pPrebandBytesItem = new QTreeWidgetItem();
   if (pPrebandBytesItem != NULL)
   {
      QString strPrebandBytes;
      QColor cellColor = Qt::lightGray;

      if (interleave == BSQ)
      {
         strPrebandBytes = QString::number(pRasterDescriptor->getPrebandBytes());
         cellColor = Qt::white;
      }

      pPrebandBytesItem->setText(0, "Preband Bytes");
      pPrebandBytesItem->setText(1, strPrebandBytes);
      pPrebandBytesItem->setBackgroundColor(1, cellColor);

      mpTreeWidget->insertTopLevelItem(12, pPrebandBytesItem);
      if ((mReadOnly == false) && (interleave == BSQ))
      {
         mpTreeWidget->setCellWidgetType(pPrebandBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }

   // Postband bytes
   QTreeWidgetItem* pPostbandBytesItem = new QTreeWidgetItem();
   if (pPostbandBytesItem != NULL)
   {
      QString strPostbandBytes;
      QColor cellColor = Qt::lightGray;

      if (interleave == BSQ)
      {
         strPostbandBytes = QString::number(pRasterDescriptor->getPostbandBytes());
         cellColor = Qt::white;
      }

      pPostbandBytesItem->setText(0, "Postband Bytes");
      pPostbandBytesItem->setText(1, strPostbandBytes);
      pPostbandBytesItem->setBackgroundColor(1, cellColor);

      mpTreeWidget->insertTopLevelItem(13, pPostbandBytesItem);
      if ((mReadOnly == false) && (interleave == BSQ))
      {
         mpTreeWidget->setCellWidgetType(pPostbandBytesItem, 1, CustomTreeWidget::LINE_EDIT);
      }
   }
}