1 #include "ImageFileListWidget.h"
6 #include <QApplication>
7 #include <QContextMenuEvent>
10 #include <QHBoxLayout>
14 #include <QScrollArea>
17 #include <QVBoxLayout>
18 #include <QXmlStreamWriter>
23 #include "ImageTreeWidget.h"
24 #include "ImageTreeWidgetItem.h"
26 #include "ProgressBar.h"
30 #include "XmlStackedHandlerReader.h"
44 QHBoxLayout *layout =
new QHBoxLayout();
47 m_tree->setObjectName(
"Tree");
50 layout->setContentsMargins(0, 0, 0, 0);
52 setWhatsThis(
"This is the image file list. Opened "
53 "cubes show up here. You can arrange your cubes into groups (that you "
54 "name) to help keep track of them. Also, you can configure multiple "
55 "files at once. Finally, you can sort your files by any of the visible "
56 "columns (use the view menu to show/hide columns of data).");
89 if (pvl.
name() ==
"ImageFileList") {
91 ImageTreeWidgetItem::TreeColumn col =
92 ImageTreeWidgetItem::FootprintColumn;
93 while (col < ImageTreeWidgetItem::BlankColumn) {
94 IString key = ImageTreeWidgetItem::treeColumnToString(col) +
"Visible";
108 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
112 m_tree->sortItems(pvl[
"SortColumn"], Qt::AscendingOrder);
117 while (
m_tree->topLevelItemCount() > 0) {
119 allCubes.append(group->takeChildren());
126 for (
int cubeGrp = 0; cubeGrp < pvl.
objects(); cubeGrp ++) {
132 bool expanded = (cubes[
"Expanded"][0] !=
"No");
133 newCubeGrp->setExpanded(expanded);
137 if (allCubes.size()) {
138 m_tree->addGroup(
"",
"Unknown")->addChildren(allCubes);
155 ImageTreeWidgetItem::TreeColumn col =
156 ImageTreeWidgetItem::FootprintColumn;
157 while (col < ImageTreeWidgetItem::BlankColumn) {
158 IString key = ImageTreeWidgetItem::treeColumnToString(col) +
"Visible";
160 bool visible = !
m_tree->isColumnHidden(col);
163 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
169 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
172 group->text(ImageTreeWidgetItem::NameColumn));
173 cubeGroup +=
PvlKeyword(
"Expanded", group->isExpanded() ?
"Yes" :
"No");
175 for (
int j = 0; j < group->childCount(); j++) {
178 if (item->type() == QTreeWidgetItem::UserType) {
181 cubeGroup +=
PvlKeyword(
"Image", cubeItem->image()->
id());
197 xmlReader->pushContentHandler(
new XmlHandler(
this));
219 return m_tree->getViewActions();
233 "Save Entire Cube List (ordered by &file list/groups)...");
234 connect(saveList, SIGNAL(triggered()),
this, SLOT(
saveList()));
236 exportActs.append(saveList);
247 QScrollArea *longHelpWidgetScrollArea =
new QScrollArea;
250 longHelpWidgetScrollArea->setWidget(longHelpWidget);
252 QVBoxLayout *longHelpLayout =
new QVBoxLayout;
253 longHelpLayout->setSizeConstraint(QLayout::SetFixedSize);
254 longHelpWidget->setLayout(longHelpLayout);
256 QLabel *title =
new QLabel(
"<h2>Image File List</h2>");
257 longHelpLayout->addWidget(title);
260 if (!fileListContainer) {
266 tmp->resize(QSize(500, 200));
267 preview = tmp->grab();
271 QPixmap previewPixmap = fileListContainer->grab().scaled(
272 QSize(500, 200), Qt::KeepAspectRatio, Qt::SmoothTransformation);
274 QLabel *previewWrapper =
new QLabel;
275 previewWrapper->setPixmap(previewPixmap);
276 longHelpLayout->addWidget(previewWrapper);
279 QLabel *previewWrapper =
new QLabel;
280 previewWrapper->setPixmap(preview);
281 longHelpLayout->addWidget(previewWrapper);
283 QLabel *overview =
new QLabel(tr(
"The mosaic file list is designed to help "
284 "to organize your files within the %1 project. The file list supports changing multiple "
285 "files simultaneously using the right-click menus after selecting "
286 "several images or groups.<br>"
288 "<p>Every cube must be inside of a group. These groups can be "
289 "renamed by double clicking on them. To move a cube between groups, "
290 "click and drag it to the group you want it in. This works "
291 "for multiple cubes also. You can change all of the cubes in a "
292 "group by right clicking on the group name. You can add a group "
293 "by right clicking in the white space below the last cube or on "
294 "an existing group.</p>"
296 "Show and hide columns by using the view menu. These "
297 "columns show relevant data about the cube, including statistical "
298 "information. Some of this information will be blank if you do "
299 "not run the application, <i>camstats</i>, before opening the cube."
301 "Sort cubes within each group in ascending or descending order "
302 "by clicking on the column "
303 "title of the column that you want to sort on. Clicking on the "
304 "title again will reverse the sorting order. You can also drag and "
305 "drop a cube between two other cubes to change where it is in the "
306 "list.").arg(QApplication::applicationName()));
307 overview->setWordWrap(
true);
309 longHelpLayout->addWidget(overview);
310 longHelpLayout->addStretch();
312 return longHelpWidgetScrollArea;
339 while (
m_tree->topLevelItemCount()) {
340 groups.append(
m_tree->takeTopLevelItem(0));
345 foreach (
Image *image, *images) {
346 if (alreadyViewedImages.indexOf(image) == -1) {
349 if (!m_serialized.isNull()) {
355 if (!pos.isValid()) {
356 if (
m_tree->groupInList(selected)) {
357 QListIterator<QTreeWidgetItem *> it(selected);
358 while (it.hasNext() && !selectedGroup) {
360 if (item->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageGroupType) {
361 selectedGroup = item;
366 if (!selectedGroup) {
370 if (images->
name().isEmpty()) {
371 imageListNameItem =
m_tree->invisibleRootItem();
372 groupName = QString(
"Group %1").arg(groups.count() + 1);
375 for (
int i = 0; !imageListNameItem && i < groups.count(); i++) {
377 if (group->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageListNameType &&
378 group->text(0) == images->
name()) {
379 imageListNameItem = group;
383 if (!imageListNameItem) {
384 imageListNameItem =
m_tree->createImageListNameItem(images->
name());
385 groups.append(imageListNameItem);
389 selectedGroup =
m_tree->createGroup(imageListNameItem, groupName);
392 selectedGroup->addChild(newImageItem);
396 if (groupItem->childCount() < pos.index())
397 groupItem->addChild(newImageItem);
399 groupItem->insertChild(pos.index(), newImageItem);
407 m_tree->addTopLevelItem(group);
412 selectedGroup->setSelected(
true);
429 foreach (
QAction *act, actions) {
438 menu.exec(event->globalPos());
446 QFileDialog::getSaveFileName((
QWidget *)parent(),
447 "Choose output file",
448 QDir::currentPath() +
"/files.lis",
449 QString(
"List File (*.lis);;Text File (*.txt);;All Files (*.*)"));
450 if (output.isEmpty())
return;
454 for (
int i = 0; i <
m_tree->topLevelItemCount(); i++) {
457 for (
int j = 0; j < group->childCount(); j++) {
460 if (item->type() == QTreeWidgetItem::UserType) {
476 QString
id = image->
id();
479 for (
int objIndex = 0; !result.isValid() && objIndex < m_serialized->objects(); objIndex++) {
480 PvlObject &obj = m_serialized->object(objIndex);
482 int imageKeyOffset = 0;
483 for (
int fileKeyIndex = 0;
484 !result.isValid() && fileKeyIndex < obj.
keywords();
511 if (states.contains(
"Expanded")) {
512 item->setExpanded(states[
"Expanded"].
toBool());
515 item->setExpanded(
true);
521 while (i < item->childCount() && i < childrenStates.count()) {
526 while (i < item->childCount()) {
542 result[
"Expanded"] = item->isExpanded();
544 if (item->childCount()) {
547 for (
int i = 0; i < item->childCount(); i++) {
551 result[
"Children"] = childrenStates;
567 stream.writeStartElement(
"imageFileList");
570 stream.writeStartElement(
"widgetGeometry");
597 ImageTreeWidgetItem::TreeColumn col =
598 ImageTreeWidgetItem::FootprintColumn;
599 while (col < ImageTreeWidgetItem::BlankColumn) {
600 bool visible = !
m_tree->isColumnHidden(col);
601 bool sorted = (
m_tree->sortColumn() == col);
603 stream.writeStartElement(
"column");
604 stream.writeAttribute(
"name", ImageTreeWidgetItem::treeColumnToString(col));
605 stream.writeAttribute(
"visible", (visible?
"true" :
"false"));
606 stream.writeAttribute(
"sorted", (sorted?
"true" :
"false"));
607 stream.writeEndElement();
609 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
615 stream.writeEndElement();
630 stream.writeStartElement(
"treeLayout");
632 else if (itemToWrite->type() == QTreeWidgetItem::UserType) {
635 stream.writeStartElement(
"image");
636 stream.writeAttribute(
"id", imageItemToWrite->image()->
id());
639 bool groupIsImageList =
640 (itemToWrite->data(0, Qt::UserRole).toInt() == ImageTreeWidget::ImageListNameType);
642 stream.writeStartElement(
"group");
643 stream.writeAttribute(
"name", itemToWrite->text(ImageTreeWidgetItem::NameColumn));
644 stream.writeAttribute(
"expanded", itemToWrite->isExpanded() ?
"true" :
"false");
645 stream.writeAttribute(
"isImageList", groupIsImageList?
"true" :
"false");
653 if (itemToWrite == NULL && i < m_tree->topLevelItemCount()) {
654 childItemToWrite =
m_tree->topLevelItem(i);
656 else if (itemToWrite != NULL && i < itemToWrite->childCount()) {
657 childItemToWrite = itemToWrite->child(i);
660 if (childItemToWrite) {
661 save(stream, childItemToWrite);
664 done = (childItemToWrite == NULL);
669 stream.writeEndElement();
702 const QString &localName,
const QString &qName,
const QXmlAttributes &atts) {
703 bool result = XmlStackedHandler::startElement(namespaceURI, localName, qName, atts);
788 const QString &localName,
const QString &qName) {
789 bool result = XmlStackedHandler::endElement(namespaceURI, localName, qName);
792 if (localName ==
"group") {
793 if (m_currentGroup) {
794 m_currentGroup = NULL;
797 m_currentImageList = NULL;
798 m_currentImageListItem = NULL;
PvlObject & object(const int index)
Return the object at the specified index.
Internalizes a list of images and allows for operations on the entire list.
The main project for cnetsuite.
QString id() const
Get a unique, identifying string associated with this image.
QString ToQt() const
Retuns the object string as a QString.
bool isNamed(QString name) const
Determines whether two PvlKeywords have the same name or not.
File name manipulation and expansion.
QString fileName() const
Get the file name of the cube that this image represents.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
QString name() const
Get the human-readable name of this image list.
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 hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
#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"...
int objects() const
Returns the number of objects.
A single keyword-value pair.
This represents a cube in a project-based GUI interface.
Provides access to sequential ASCII stream I/O.
bool toBool(const QString &string)
Global function to convert from a string to a boolean.
void PutLine(const QString &line)
Writes string to file and appends a 'newline' string.
Adds specific functionality to C++ strings.
QProgressBar with customizable text.
Contains Pvl Groups and Pvl Objects.
his enables stack-based XML parsing of XML files.
QString name() const
Returns the container name.