1#include "ImageTreeWidget.h"
10#include <QProgressBar>
16#include "IException.h"
20#include "ImageTreeWidgetItem.h"
21#include "ProgressBar.h"
33 m_queuedSelectionChanged =
false;
34 m_directory = directory;
38 ImageTreeWidgetItem::TreeColumn col = ImageTreeWidgetItem::NameColumn;
39 while(col < ImageTreeWidgetItem::BlankColumn) {
40 header << ImageTreeWidgetItem::treeColumnToString(col);
41 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
44 setHeaderLabels(header);
46 hideColumn(ImageTreeWidgetItem::ImageColumn);
47 hideColumn(ImageTreeWidgetItem::LabelColumn);
48 hideColumn(ImageTreeWidgetItem::ResolutionColumn);
49 hideColumn(ImageTreeWidgetItem::EmissionAngleColumn);
50 hideColumn(ImageTreeWidgetItem::IncidenceAngleColumn);
51 hideColumn(ImageTreeWidgetItem::PhaseAngleColumn);
52 hideColumn(ImageTreeWidgetItem::AspectRatioColumn);
53 hideColumn(ImageTreeWidgetItem::SampleResolutionColumn);
54 hideColumn(ImageTreeWidgetItem::LineResolutionColumn);
55 hideColumn(ImageTreeWidgetItem::NorthAzimuthColumn);
56 hideColumn(ImageTreeWidgetItem::BlankColumn);
60 FileName(QString(
"$HOME/.Isis/%1/fileList.config").arg(QApplication::applicationName()))
62 QSettings::NativeFormat);
63 settings.beginGroup(
"ColumnsVisible");
65 col = ImageTreeWidgetItem::FootprintColumn;
66 while(col < ImageTreeWidgetItem::BlankColumn) {
67 bool visible = !isColumnHidden(col);
69 if (settings.value(QString(
"%1Visible").arg(ImageTreeWidgetItem::treeColumnToString(col)),
70 visible).
toBool() != visible) {
77 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
81 setContextMenuPolicy(Qt::DefaultContextMenu);
83 setSortingEnabled(
true);
84 sortItems(ImageTreeWidgetItem::NameColumn, Qt::AscendingOrder);
88 connect(
this, SIGNAL(itemSelectionChanged()),
89 this, SLOT(onSelectionChanged()));
93 connect(
this, SIGNAL(queueSelectionChanged()),
94 this, SLOT(onQueuedSelectionChanged()), Qt::QueuedConnection);
97 connect(
this, SIGNAL(queueReadDisplayProperties()),
98 this, SLOT(onQueuedReadDisplayProperties()), Qt::QueuedConnection);
100 setSelectionMode(QAbstractItemView::ExtendedSelection);
101 setDragDropOverwriteMode(
false);
105 ImageTreeWidget::~ImageTreeWidget() {
107 foreach(contextAction, actions()) {
108 removeAction(contextAction);
113 QList<QAction *> ImageTreeWidget::actions() {
115 QList<QAction *> results;
116 if (!m_setFileListColsAct) {
117 m_setFileListColsAct =
new QAction(
"Set Current File List &Columns as Default",
this);
118 m_setFileListColsAct->setWhatsThis(tr(
"Use the currently visible columns in the file list as "
119 "the default when no project has been opened"));
120 connect(m_setFileListColsAct, SIGNAL(triggered(
bool)),
121 this, SLOT(setDefaultFileListCols()));
123 results.append(m_setFileListColsAct);
134 QTreeWidgetItem *group = createGroup(imageList, groupName, index);
136 verticalScrollBar()->setMaximum(verticalScrollBar()->maximum() + 25);
141 QTreeWidgetItem *ImageTreeWidget::createGroup(QTreeWidgetItem *imageListItem, QString groupName,
144 imageListItem = invisibleRootItem();
146 if (groupName.isEmpty()) {
147 groupName = QString(
"Group %1").arg(imageListItem->childCount() + 1);
150 QTreeWidgetItem *result =
new QTreeWidgetItem;
151 result->setText(0, groupName);
152 result->setFlags(Qt::ItemIsEditable |
153 Qt::ItemIsUserCheckable |
155 Qt::ItemIsSelectable |
156 Qt::ItemIsDragEnabled |
157 Qt::ItemIsDropEnabled);
158 result->setData(0, Qt::UserRole, ImageGroupType);
161 index = imageListItem->childCount();
164 imageListItem->insertChild(index, result);
167 result->setExpanded(
true);
173 QTreeWidgetItem *ImageTreeWidget::createImageListNameItem(QString name) {
174 QTreeWidgetItem *result =
new QTreeWidgetItem;
175 result->setText(0, name);
176 result->setData(0, Qt::UserRole, ImageListNameType);
177 result->setExpanded(
true);
183 void ImageTreeWidget::refit() {
184 ImageTreeWidgetItem::TreeColumn col = ImageTreeWidgetItem::NameColumn;
185 while(col < ImageTreeWidgetItem::BlankColumn) {
187 if (col == ImageTreeWidgetItem::NameColumn) {
188 QList<bool> expandedStates;
189 for (
int groupIndex = 0; groupIndex < topLevelItemCount(); groupIndex++) {
190 expandedStates.append(topLevelItem(groupIndex)->isExpanded());
191 topLevelItem(groupIndex)->setExpanded(
true);
194 resizeColumnToContents(col);
196 for (
int groupIndex = 0; groupIndex < topLevelItemCount(); groupIndex++) {
197 topLevelItem(groupIndex)->setExpanded(expandedStates[groupIndex]);
201 resizeColumnToContents(col);
204 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
209 void ImageTreeWidget::disableSort() {
210 sortItems(ImageTreeWidgetItem::BlankColumn, Qt::AscendingOrder);
215 m_queuedReadDisplayPropertiesItems.append(item);
217 if (m_queuedReadDisplayPropertiesItems.count() == 1) {
218 emit queueReadDisplayProperties();
223 QList<QAction *> ImageTreeWidget::getViewActions() {
224 if (m_viewActs.empty()) {
225 ImageTreeWidgetItem::TreeColumn col =
226 ImageTreeWidgetItem::FootprintColumn;
228 while(col < ImageTreeWidgetItem::BlankColumn) {
229 QAction *showHide =
new QAction(
"",
this);
230 showHide->setData(col);
232 connect(showHide, SIGNAL(triggered()),
233 this, SLOT(toggleColumnVisible()));
235 m_viewActs.append(showHide);
237 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
247 void ImageTreeWidget::updateViewActs() {
248 if (!m_viewActs.empty()) {
249 int viewActIndex = 0;
250 ImageTreeWidgetItem::TreeColumn col =
251 ImageTreeWidgetItem::FootprintColumn;
253 while(col < ImageTreeWidgetItem::BlankColumn) {
254 bool visible = !isColumnHidden(col);
255 QAction *showHide = m_viewActs[viewActIndex];
258 showHide->setText(
"Show " +
259 ImageTreeWidgetItem::treeColumnToString(col) +
" Column");
262 showHide->setText(
"Hide " +
263 ImageTreeWidgetItem::treeColumnToString(col) +
" Column");
266 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
276 void ImageTreeWidget::setDefaultFileListCols() {
279 QString(
"$HOME/.Isis/%1/fileList.config").arg(QApplication::applicationName()))
281 QSettings::NativeFormat);
282 settings.beginGroup(
"ColumnsVisible");
284 ImageTreeWidgetItem::TreeColumn col =
285 ImageTreeWidgetItem::FootprintColumn;
287 while(col < ImageTreeWidgetItem::BlankColumn) {
288 bool visible = !isColumnHidden(col);
290 settings.setValue(QString(
"%1Visible").arg(ImageTreeWidgetItem::treeColumnToString(col)),
293 col = (ImageTreeWidgetItem::TreeColumn)(col + 1);
302 ImageTreeWidgetItem *item =
new ImageTreeWidgetItem(imageList, image);
304 connect(image->displayProperties(), SIGNAL(destroyed(QObject *)),
305 this, SLOT(imageDeleted(QObject *)));
306 connect(image->displayProperties(), SIGNAL(propertyChanged(DisplayProperties *)),
307 this, SLOT(propertiesChanged(DisplayProperties *)));
309 m_displayPropsToTreeItemLookup[image->displayProperties()] = item;
313 catch(IException &e) {
321 ImageList ImageTreeWidget::imagesInView() {
324 QTreeWidgetItemIterator it(
this, QTreeWidgetItemIterator::UserFlag);
327 QTreeWidgetItem *item = *it;
329 if (item->type() == QTreeWidgetItem::UserType) {
330 ImageTreeWidgetItem *mosItem = (ImageTreeWidgetItem *)item;
331 results.append(mosItem->image());
341 ImageTreeWidget::ImagePosition::ImagePosition() {
346 ImageTreeWidget::ImagePosition::ImagePosition(
int outerIndex,
int innerIndex) {
349 setPosition(outerIndex, innerIndex);
353 ImageTreeWidget::ImagePosition::ImagePosition(
const ImagePosition &other) :
354 m_group(other.m_group), m_index(other.m_index) {
358 ImageTreeWidget::ImagePosition::~ImagePosition() {
363 void ImageTreeWidget::ImagePosition::setPosition(
int group,
int index) {
364 if (group >= 0 && index >= 0) {
374 int ImageTreeWidget::ImagePosition::group()
const {
379 int ImageTreeWidget::ImagePosition::index()
const {
384 bool ImageTreeWidget::ImagePosition::isValid()
const {
385 return (m_group != -1 && m_index != -1);
389 void ImageTreeWidget::ImagePosition::swap(
ImagePosition &other) {
390 std::swap(m_group, other.m_group);
391 std::swap(m_index, other.m_index);
395 bool ImageTreeWidget::ImagePosition::operator<(
const ImagePosition &rhs) {
396 bool lessThan =
false;
397 if (group() < rhs.group()) {
400 else if (group() == rhs.group() && index() < rhs.index()) {
408 ImageTreeWidget::ImagePosition &ImageTreeWidget::ImagePosition::operator=(
417 void ImageTreeWidget::ImagePosition::init() {
422 void ImageTreeWidget::dropEvent(QDropEvent *event) {
423 QTreeWidgetItem *droppedAtItem = itemAt(event->pos());
427 QTreeWidgetItem *droppedAtGroup = droppedAtItem;
429 if(droppedAtGroup->type() != QTreeWidgetItem::Type)
430 droppedAtGroup = droppedAtItem->parent();
432 bool draggedGroup = groupInList(selectedItems());
433 bool draggedItem = mosaicItemInList(selectedItems());
436 if(draggedItem && !draggedGroup) {
437 int insertPosition = 0;
439 if(droppedAtGroup != droppedAtItem) {
440 insertPosition = droppedAtGroup->indexOfChild(droppedAtItem) + 1;
443 QTreeWidgetItem *toBeMoved;
444 foreach(toBeMoved, selectedItems()) {
445 if(toBeMoved != droppedAtItem) {
446 QTreeWidgetItem *parent = toBeMoved->parent();
450 int childOrigIndex = parent->indexOfChild(toBeMoved);
452 parent->takeChild(childOrigIndex);
454 int actualInsertPos = insertPosition;
456 if(parent == droppedAtGroup && childOrigIndex < insertPosition)
459 droppedAtGroup->insertChild(actualInsertPos, toBeMoved);
462 if(insertPosition != droppedAtGroup->childCount())
467 else if(!draggedItem && draggedGroup) {
468 QTreeWidgetItem *toBeMoved;
470 foreach(toBeMoved, selectedItems()) {
471 if(toBeMoved != droppedAtGroup) {
472 int dropPosition = indexOfTopLevelItem(droppedAtGroup);
474 takeTopLevelItem(indexOfTopLevelItem(toBeMoved));
475 insertTopLevelItem(dropPosition, toBeMoved);
598 switch(event->type()) {
599 case QEvent::MouseButtonPress: {
600 if (event->button() == Qt::RightButton &&
601 itemAt(event->pos()) == NULL) {
602 setCurrentItem(NULL);
611 QTreeWidget::mousePressEvent(event);
615 void ImageTreeWidget::contextMenuEvent(QContextMenuEvent *event) {
616 ImageList selectedCubes = selectedDisplays();
618 bool selectedGroup = groupInList(selectedItems());
619 bool selectedCube = mosaicItemInList(selectedItems());
624 project = m_directory->
project();
629 supportedActions.append(NULL);
634 foreach(
QAction *action, supportedActions) {
636 menu.addAction(action);
643 if (!selectedCube && selectedGroup) {
644 if (selectedItems().size() == 1 && selectedItems()[0]->childCount()) {
645 QAction *close = menu.addAction(
"Close Cubes in Group");
646 connect(close, SIGNAL(triggered()),
647 this, SLOT(requestCloseSelected()));
650 if (selectedItems().size() == 1) {
651 QAction *rename = menu.addAction(
"Rename Group");
652 connect(rename, SIGNAL(triggered()),
653 this, SLOT(renameSelectedGroup()));
655 QAction *group = menu.addAction(
"Insert Group");
656 connect(group, SIGNAL(triggered()),
660 QAction *removeGroup = NULL;
662 if (selectedItems().size() == 1)
663 removeGroup = menu.addAction(
"Delete Group");
665 removeGroup = menu.addAction(
"Delete Groups");
667 connect(removeGroup, SIGNAL(triggered()),
668 this, SLOT(deleteSelectedGroups()));
671 if (selectedCube && !selectedGroup) {
672 QAction *close = NULL;
674 if (selectedItems().size() == 1)
675 close = menu.addAction(
"Close Cube");
677 close = menu.addAction(
"Close Cubes");
679 connect(close, SIGNAL(triggered()),
680 this, SLOT(requestCloseSelected()));
683 if (!selectedCube && !selectedGroup) {
684 QAction *group = menu.addAction(
"Add Group");
686 connect(group, SIGNAL(triggered()),
690 menu.exec(event->globalPos());
704 QString newGroupParentText =
"";
706 if (selectedItems().size() == 1) {
707 if (selectedItems()[0]->data(0, Qt::UserRole).
toInt() == ImageGroupType) {
708 newGroupParent = selectedItems()[0]->parent();
709 if (newGroupParent) {
710 index = newGroupParent->indexOfChild(selectedItems()[0]);
713 newGroupParent = invisibleRootItem();
714 index = indexOfTopLevelItem(selectedItems()[0]);
717 else if (selectedItems()[0]->data(0, Qt::UserRole).
toInt() == ImageListNameType) {
718 newGroupParent = selectedItems()[0];
722 if (newGroupParent) {
723 newGroupParentText = newGroupParent->text(0);
725 return addGroup(newGroupParentText,
"", index);
729 void ImageTreeWidget::deleteSelectedGroups() {
731 requestCloseSelected();
734 foreach(toBeDeleted, selectedItems()) {
735 if (toBeDeleted->type() == QTreeWidgetItem::Type) {
742 void ImageTreeWidget::imageDeleted(QObject *imageObj) {
743 ImageDisplayProperties *imagedisp = (ImageDisplayProperties *)imageObj;
744 ImageTreeWidgetItem *item = treeItem(imagedisp);
746 if (item && item->parent()) {
747 m_displayPropsToTreeItemLookup.remove(imagedisp);
750 delete item->parent()->takeChild( item->parent()->indexOfChild(item) );
755 void ImageTreeWidget::onItemChanged(QTreeWidgetItem *item,
int) {
756 if (item->type() == QTreeWidgetItem::UserType) {
757 ((ImageTreeWidgetItem *)item)->update(
true);
762 void ImageTreeWidget::onSelectionChanged() {
763 if (!m_queuedSelectionChanged) {
764 emit queueSelectionChanged();
765 m_queuedSelectionChanged =
true;
770 void ImageTreeWidget::onQueuedReadDisplayProperties() {
771 QTreeWidgetItem *newlySelectedItem = NULL;
773 foreach (ImageTreeWidgetItem *item, m_queuedReadDisplayPropertiesItems) {
774 bool wasSelected = item->isSelected();
777 if (!wasSelected && item->isSelected()) {
778 newlySelectedItem = item;
782 if (newlySelectedItem) {
783 scrollToItem(newlySelectedItem);
786 m_queuedReadDisplayPropertiesItems.clear();
790 void ImageTreeWidget::onQueuedSelectionChanged() {
793 m_queuedSelectionChanged =
false;
795 QTreeWidgetItemIterator it(
this, QTreeWidgetItemIterator::UserFlag);
798 QTreeWidgetItem *item = *it;
800 if (item->type() == QTreeWidgetItem::UserType) {
801 ImageTreeWidgetItem *imageItem = (ImageTreeWidgetItem *)item;
802 imageItem->update(
true);
808 updateDragAndDropability();
812 void ImageTreeWidget::propertiesChanged(DisplayProperties *changed) {
813 enqueueReadDisplayProperties(treeItem(changed));
817 void ImageTreeWidget::renameSelectedGroup() {
818 if (selectedItems().size() == 1 &&
819 selectedItems()[0]->type() == QTreeWidgetItem::Type) {
820 QTreeWidgetItem *groupToEdit = selectedItems()[0];
821 editItem(groupToEdit);
826 void ImageTreeWidget::requestCloseSelected() {
827 QTreeWidgetItemIterator it(
this, QTreeWidgetItemIterator::UserFlag);
830 QTreeWidgetItem *item = *it;
833 if (item->type() == QTreeWidgetItem::UserType) {
834 if (item->isSelected() || item->parent()->isSelected()) {
835 ImageTreeWidgetItem *mosItem = (ImageTreeWidgetItem *)item;
836 mosItem->image()->deleteLater();
845 void ImageTreeWidget::toggleColumnVisible() {
846 int column = ((QAction *)sender())->data().toInt();
847 setColumnHidden(column, !isColumnHidden(column));
849 if (!m_viewActs.empty())
856 void ImageTreeWidget::updateDragAndDropability() {
857 QList<QTreeWidgetItem *> selected = selectedItems();
858 bool selectedGroup = groupInList(selected);
859 bool selectedItem = mosaicItemInList(selected);
861 if (selectedGroup && selectedItem) {
862 setDragDropMode(QAbstractItemView::NoDragDrop);
865 setDragDropMode(QAbstractItemView::DragDrop);
870 bool ImageTreeWidget::groupInList(QList<QTreeWidgetItem *> items) {
871 QListIterator<QTreeWidgetItem *> it(items);
873 while (it.hasNext()) {
874 QTreeWidgetItem *item = it.next();
876 if (item->type() == QTreeWidgetItem::Type)
884 bool ImageTreeWidget::mosaicItemInList(QList<QTreeWidgetItem *> items) {
885 QListIterator<QTreeWidgetItem *> it(items);
887 while (it.hasNext()) {
888 QTreeWidgetItem *item = it.next();
890 if (item->type() == QTreeWidgetItem::UserType)
897 ImageList ImageTreeWidget::selectedDisplays() {
899 QTreeWidgetItemIterator it(
this, QTreeWidgetItemIterator::UserFlag);
902 QTreeWidgetItem *item = *it;
905 if (item->type() == QTreeWidgetItem::UserType) {
906 ImageTreeWidgetItem *mosItem = (ImageTreeWidgetItem *)item;
907 if (mosItem->isSelected() || mosItem->parent()->isSelected()) {
908 selected.append(mosItem->image());
930 if (imageListName.isEmpty()) {
931 result = invisibleRootItem();
934 QTreeWidgetItemIterator it(
this);
936 while(*it && !result) {
939 if (item->data(0, Qt::UserRole).toInt() == ImageListNameType) {
940 if (item->text(0) == imageListName) {
950 result = createImageListNameItem(imageListName);
951 addTopLevelItem(result);
959 return m_displayPropsToTreeItemLookup[displayProps];
963 ImageTreeWidgetItem *ImageTreeWidget::treeItem(Image *image) {
964 return treeItem(image->displayProperties());
QList< QAction * > supportedActions(DataType data)
Returns a list of supported actions for a WorkOrder.
Project * project() const
Gets the Project for this directory.
File name manipulation and expansion.
This represents a cube in a project-based GUI interface.
Internalizes a list of images and allows for operations on the entire list.
QList< QAction * > supportedActions(Project *project=NULL)
Gets a list of pre-connected actions that have to do with display.
The main project for ipce.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
int toInt(const QString &string)
Global function to convert from a string to an integer.
bool toBool(const QString &string)
Global function to convert from a string to a boolean.