+
+void LayerWidget::Reload(void)
+{
+ list->clear();
+
+ for(int i=0; i<Global::numLayers; i++)
+ {
+ QListWidgetItem * qlwi = new QListWidgetItem();
+ LayerItemWidget * liw = new LayerItemWidget(Global::layerName[i].c_str(), Global::layerHidden[i], Global::layerLocked[i], qlwi);
+ list->insertItem(0, qlwi);
+ list->setItemWidget(qlwi, liw);
+
+ // Set up SIGNAL/SLOTs for this LayerItemWidget
+ connect(liw, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+ connect(liw, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+ }
+
+ int layer = (Global::numLayers - Global::activeLayer) - 1;
+ list->setCurrentRow(layer, QItemSelectionModel::SelectCurrent);
+ SetButtonStates();
+}
+
+
+void LayerWidget::HandleLayerSelected(int currentRow)
+{
+ // If LayerWidget is empty, bail out
+ if (currentRow == -1)
+ return;
+
+ // This is numbered opposite of how it's presented. In other words, the
+ // bottom of the list is 0, and items above it count upwards. So like this:
+ //
+ // (2) Layer #2
+ // (1) Layer #1
+ // (0) Background
+ //
+ // which is the opposite of the internal numbering.
+ Global::activeLayer = (Global::numLayers - currentRow) - 1;
+
+ // Set button states to sane values
+ SetButtonStates();
+}
+
+
+//
+// What happens here is that for every QListWidgetItem we make, we connect it
+// to these handlers. But we only have to worry about that when adding and
+// moving a layer. However, when toggling states, we need to toggle the global
+// state variables too.
+//
+void LayerWidget::HandleHideToggle(QListWidgetItem * qlwi, bool state)
+{
+ int currentRow = list->row(qlwi);
+ int layer = (Global::numLayers - currentRow) - 1;
+ std::vector<bool>::iterator i = Global::layerHidden.begin() + layer;
+ (*i) = state;
+//printf("Item #%i, new hide state is %s\n", currentRow, (state ? "ON" : "off"));
+//printf("LayerWidget: New hide state of layer %i is %s.\n", layer, (state ? "ON" : "off"));
+ // We do this last, because otherwise the Document would get the wrong state
+ emit LayerToggled();
+}
+
+
+void LayerWidget::HandleLockToggle(QListWidgetItem * qlwi, bool state)
+{
+ int currentRow = list->row(qlwi);
+ int layer = (Global::numLayers - currentRow) - 1;
+ std::vector<bool>::iterator i = Global::layerLocked.begin() + layer;
+ (*i) = state;
+// printf("Item #%i, new lock state is %s\n", list->row(qlwi), (state ? "ON" : "off"));
+}
+
+
+void LayerWidget::HandleDblClick(QListWidgetItem * /*qlwi*/)
+{
+ EditLayer();
+}
+
+
+void LayerWidget::AddLayer(void)
+{
+ // We always stick the newest layer at the top of the list (visually, the
+ // top of the list is the end, the bottom is the beginning)...
+ int count = list->count();
+ QString text = QString("Layer #%1").arg(count);
+ QListWidgetItem * qlwi = new QListWidgetItem();
+ LayerItemWidget * liw = new LayerItemWidget(text, false, false, qlwi);
+ list->insertItem(0, qlwi);
+ list->setItemWidget(qlwi, liw);
+
+ // Set up SIGNAL/SLOTs for this LayerItemWidget
+ connect(liw, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+ connect(liw, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+ SetButtonStates();
+
+ // Fix up the global state
+ Global::layerHidden.push_back(false);
+ Global::layerLocked.push_back(false);
+ Global::layerName.push_back(text.toUtf8().data());
+ Global::numLayers++;
+}
+
+
+void LayerWidget::DeleteLayer(void)
+{
+ int numItems = list->count();
+
+ if (numItems == 1)
+ return;
+
+ // N.B.: This *must* go before the item removal because that causes
+ // HandleLayerSelected() to be fired off which causes the numbers to
+ // be off. You have been warned!
+ // Tell the DrawingView to delete this layer in its Container:
+ emit LayerDeleted(Global::activeLayer);
+
+ int currentRow = list->currentRow();
+ QListWidgetItem * qlwi = list->currentItem();
+ list->removeItemWidget(qlwi);
+ delete qlwi;
+
+ SetButtonStates();
+
+ // Fix up the global state
+ int layer = (Global::numLayers - currentRow) - 1;
+ Global::layerHidden.erase(Global::layerHidden.begin() + layer);
+ Global::layerLocked.erase(Global::layerLocked.begin() + layer);
+ Global::layerName.erase(Global::layerName.begin() + layer);
+ Global::numLayers--;
+
+ // If we're deleting from the top of the list, we have to decrement the
+ // active layer # by 1 (since we count upward from the bottom of the list).
+ if (currentRow == 0)
+ Global::activeLayer--;
+}
+
+
+void LayerWidget::EditLayer(void)
+{
+ // Get the LayerItemWidget so we can edit it (its name, anyway)...
+ QListWidgetItem * qlwi = list->currentItem();
+ LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+ QString s = li->name->text();
+
+ bool ok;
+ QString result = QInputDialog::getText(this, tr("Edit Layer Name"), tr("Layer Name:"), QLineEdit::Normal, s, &ok);
+
+ if (ok && !result.isEmpty())
+ {
+ li->name->setText(result);
+
+ int layer = (Global::numLayers - Global::activeLayer) - 1;
+ std::vector<std::string>::iterator i = Global::layerName.begin() + layer;
+ (*i) = result.toUtf8().data();
+ }
+}
+
+
+void LayerWidget::MoveLayerUp(void)
+{
+ // Get information out of the LayerItemWidget (& get it from the list!)
+ int currentRow = list->currentRow();
+ QListWidgetItem * qlwi = list->currentItem();
+ LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+ QString s = li->name->text();
+ bool visible = li->invisible->isChecked();
+ bool editible = li->locked->isChecked();
+
+ // We have to make a new LayerItemWidget because it destroys the old one!
+ list->takeItem(currentRow);
+ list->insertItem(currentRow - 1, qlwi);
+ li = new LayerItemWidget(s, visible, editible, qlwi);
+ list->setItemWidget(qlwi, li);
+ list->setCurrentItem(qlwi);
+
+ // Set up SIGNAL/SLOTs for this LayerItemWidget
+ connect(li, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+ connect(li, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+ // Fix up the global state...
+ // N.B.: Because we handle the button states correctly, we should never
+ // have a situation where the reference in the vector is bad.
+ int layer = (Global::numLayers - currentRow) - 1;
+ bool old = Global::layerHidden[layer];
+ Global::layerHidden[layer] = Global::layerHidden[layer + 1];
+ Global::layerHidden[layer + 1] = old;
+ old = Global::layerLocked[layer];
+ Global::layerLocked[layer] = Global::layerLocked[layer + 1];
+ Global::layerLocked[layer + 1] = old;
+ std::string oldStr = Global::layerName[layer];
+ Global::layerName[layer] = Global::layerName[layer + 1];
+ Global::layerName[layer + 1] = oldStr;
+ // We also have to tell the document to shuffle its layers too
+ emit LayersSwapped(layer, layer + 1);
+}
+
+
+void LayerWidget::MoveLayerDown(void)
+{
+ // Get information out of the LayerItemWidget (& get it from the list!)
+ int currentRow = list->currentRow();
+ QListWidgetItem * qlwi = list->currentItem();
+ LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+ QString s = li->name->text();
+ bool visible = li->invisible->isChecked();
+ bool editible = li->locked->isChecked();
+
+ // We have to make a new LayerItemWidget because it destroys the old one!
+ list->takeItem(currentRow);
+ list->insertItem(currentRow + 1, qlwi);
+ li = new LayerItemWidget(s, visible, editible, qlwi);
+ list->setItemWidget(qlwi, li);
+ list->setCurrentItem(qlwi);
+
+ // Set up SIGNAL/SLOTs for this LayerItemWidget
+ connect(li, SIGNAL(HideToggled(QListWidgetItem *, bool)), this, SLOT(HandleHideToggle(QListWidgetItem *, bool)));
+ connect(li, SIGNAL(LockToggled(QListWidgetItem *, bool)), this, SLOT(HandleLockToggle(QListWidgetItem *, bool)));
+
+ // Fix up the global state...
+ // N.B.: Because we handle the button states correctly, we should never
+ // have a situation where the reference in the vector is bad.
+ int layer = (Global::numLayers - currentRow) - 1;
+ bool old = Global::layerHidden[layer];
+ Global::layerHidden[layer] = Global::layerHidden[layer - 1];
+ Global::layerHidden[layer - 1] = old;
+ old = Global::layerLocked[layer];
+ Global::layerLocked[layer] = Global::layerLocked[layer - 1];
+ Global::layerLocked[layer - 1] = old;
+ std::string oldStr = Global::layerName[layer];
+ Global::layerName[layer] = Global::layerName[layer - 1];
+ Global::layerName[layer - 1] = oldStr;
+ // We also have to tell the document to shuffle its layers too
+ emit LayersSwapped(layer, layer - 1);
+}
+
+
+//
+// Set button states in this widget to sane values
+//
+void LayerWidget::SetButtonStates(void)
+{
+ int numItems = list->count();
+ int currentRow = list->currentRow();
+
+ layerDown->setEnabled(currentRow == (numItems - 1) ? false : true);
+ layerUp->setEnabled(currentRow == 0 ? false : true);
+ removeLayer->setEnabled(numItems == 1 ? false : true);
+}
+