|
@@ -80,6 +80,12 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
|
|
|
menu_file_ = new QMenu(menu_bar_);
|
|
|
menu_file_->setTitle(tr("&File"));
|
|
|
+
|
|
|
+ menu_save_ = new QMenu(menu_bar_);
|
|
|
+ menu_save_->setTitle(tr("&Save"));
|
|
|
+ menu_load_ = new QMenu(menu_bar_);
|
|
|
+ menu_load_->setTitle(tr("&Load"));
|
|
|
+
|
|
|
menu_pascal_ = new QMenu(menu_bar_);
|
|
|
menu_pascal_->setTitle(tr("&Pascal"));
|
|
|
menu_view_ = new QMenu(menu_bar_);
|
|
@@ -151,15 +157,18 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
action_about_->setEnabled(false);
|
|
|
/* ------------------ */
|
|
|
|
|
|
- menu_file_->addAction(action_open_image_);
|
|
|
- menu_file_->addAction(action_open_images_);
|
|
|
- menu_file_->addAction(action_open_labeled_image_);
|
|
|
- menu_file_->addAction(action_load_legend_);
|
|
|
+ menu_load_->addAction(action_open_image_);
|
|
|
+ menu_load_->addAction(action_open_images_);
|
|
|
+ menu_load_->addAction(action_open_labeled_image_);
|
|
|
+ menu_load_->addAction(action_load_legend_);
|
|
|
+ menu_save_->addAction(action_save_segmented_);
|
|
|
+ menu_save_->addAction(action_save_legend_);
|
|
|
+ menu_save_->addAction(action_save_all_);
|
|
|
+ menu_file_->addAction(menu_load_->menuAction());
|
|
|
+ menu_file_->addAction(menu_save_->menuAction());
|
|
|
menu_file_->addAction(menu_pascal_->menuAction());
|
|
|
- menu_file_->addSeparator();
|
|
|
- menu_file_->addAction(action_save_segmented_);
|
|
|
- menu_file_->addAction(action_save_legend_);
|
|
|
- menu_file_->addAction(action_save_all_);
|
|
|
+ //menu_file_->addSeparator();
|
|
|
+
|
|
|
menu_file_->addSeparator();
|
|
|
menu_file_->addAction(action_quit_);
|
|
|
|
|
@@ -247,13 +256,14 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
image_ = new QPixmap(500, 500);
|
|
|
image_->fill(QColor(Qt::white));
|
|
|
|
|
|
- image_holder_ = new ImageHolder;//(frame_image_);
|
|
|
+ image_holder_ = new ImageHolder;
|
|
|
image_holder_->setPixmap(*image_);
|
|
|
image_holder_->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
|
|
|
image_holder_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
image_holder_->setScaledContents(true);
|
|
|
image_holder_->setFrameStyle(QFrame::Box | QFrame::Plain);
|
|
|
image_holder_->setLineWidth(0);
|
|
|
+ image_holder_->setFocusPolicy(Qt::StrongFocus);
|
|
|
|
|
|
frame_image_->setWidget(image_holder_);
|
|
|
|
|
@@ -265,6 +275,7 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
list_images_widget_->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
|
|
label_toolbox_ = new QLabel(tr("Tool box"), frame_toolbox_);
|
|
|
+ label_list_label_ = new QLabel(tr("Object labels:"), central_widget_);
|
|
|
label_list_areas_ = new QLabel(tr("Selected areas:"), central_widget_);
|
|
|
label_list_images_ = new QLabel(tr("Loaded images:"), central_widget_);
|
|
|
|
|
@@ -305,6 +316,22 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
button_remove_label_->setText(tr("Remove label"));
|
|
|
button_remove_label_->setEnabled(false);
|
|
|
|
|
|
+ button_delete_area_ = new QPushButton(frame_labelbox_);
|
|
|
+ button_delete_area_->setText(tr("Delete area"));
|
|
|
+ button_delete_area_->setEnabled(false);
|
|
|
+ button_change_area_ = new QPushButton(frame_labelbox_);
|
|
|
+ button_change_area_->setText(tr("Change area"));
|
|
|
+ button_change_area_->setEnabled(false);
|
|
|
+ button_change_area_text_ = new QPushButton(frame_labelbox_);
|
|
|
+ button_change_area_text_->setText(tr("Change area text"));
|
|
|
+ button_change_area_text_->setEnabled(false);
|
|
|
+
|
|
|
+ button_add_image_ = new QPushButton(frame_toolbox_);
|
|
|
+ button_add_image_->setText(tr("Add"));
|
|
|
+ button_remove_image_ = new QPushButton(frame_toolbox_);
|
|
|
+ button_remove_image_->setText(tr("Remove"));
|
|
|
+ button_remove_image_->setEnabled(false);
|
|
|
+
|
|
|
button_prev_image_ = new QPushButton(central_widget_);
|
|
|
button_prev_image_->setText("←");
|
|
|
button_next_image_ = new QPushButton(central_widget_);
|
|
@@ -316,6 +343,7 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
layout_main_ = new QHBoxLayout(central_widget_);
|
|
|
layout_left_ = new QVBoxLayout();
|
|
|
layout_toolbox_ = new QVBoxLayout();
|
|
|
+ layout_imagelist_buttons_ = new QHBoxLayout();
|
|
|
layout_center_ = new QVBoxLayout();
|
|
|
layout_frame_image_ = new QVBoxLayout();
|
|
|
layout_image_widget_ = new QGridLayout();
|
|
@@ -323,6 +351,7 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
layout_right_ = new QVBoxLayout();
|
|
|
layout_labelbox_ = new QVBoxLayout();
|
|
|
layout_labelbox_buttons_ = new QHBoxLayout();
|
|
|
+ layout_areabox_buttons_ = new QVBoxLayout();
|
|
|
|
|
|
layout_main_->addLayout(layout_left_);
|
|
|
layout_main_->addLayout(layout_center_);
|
|
@@ -348,6 +377,11 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
/* stretch is for making toolbox as small as it can be */
|
|
|
layout_toolbox_->addSpacing(10);
|
|
|
layout_left_->addWidget(label_list_images_);
|
|
|
+
|
|
|
+ layout_left_->addLayout(layout_imagelist_buttons_);
|
|
|
+ layout_imagelist_buttons_->addWidget(button_add_image_);
|
|
|
+ layout_imagelist_buttons_->addWidget(button_remove_image_);
|
|
|
+
|
|
|
layout_left_->addWidget(list_images_widget_);
|
|
|
list_images_widget_->setFixedWidth(200);
|
|
|
layout_left_->addStretch(1);
|
|
@@ -370,12 +404,21 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
frame_labelbox_->setFixedWidth(200);
|
|
|
frame_labelbox_->setLayout(layout_labelbox_);
|
|
|
|
|
|
+ layout_labelbox_->addWidget(label_list_label_);
|
|
|
+
|
|
|
layout_labelbox_->addLayout(layout_labelbox_buttons_);
|
|
|
layout_labelbox_buttons_->addWidget(button_add_label_);
|
|
|
layout_labelbox_buttons_->addWidget(button_remove_label_);
|
|
|
|
|
|
layout_labelbox_->addWidget(list_label_);
|
|
|
layout_labelbox_->addWidget(label_list_areas_);
|
|
|
+
|
|
|
+ layout_labelbox_->addLayout(layout_areabox_buttons_);
|
|
|
+ layout_areabox_buttons_->addWidget(button_delete_area_);
|
|
|
+ layout_areabox_buttons_->addWidget(button_change_area_);
|
|
|
+ layout_areabox_buttons_->addWidget(button_change_area_text_);
|
|
|
+ layout_areabox_buttons_->setSpacing(0);
|
|
|
+
|
|
|
layout_labelbox_->addWidget(list_areas_);
|
|
|
|
|
|
connect(
|
|
@@ -462,6 +505,12 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
image_holder_,
|
|
|
SLOT(redo())
|
|
|
);
|
|
|
+ connect(
|
|
|
+ action_tagging_tool_,
|
|
|
+ SIGNAL(triggered()),
|
|
|
+ &line_edit_form_,
|
|
|
+ SLOT(setTags())
|
|
|
+ );
|
|
|
connect(
|
|
|
action_add_description_,
|
|
|
SIGNAL(triggered()),
|
|
@@ -483,7 +532,26 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
connect(
|
|
|
button_remove_label_,
|
|
|
SIGNAL(clicked()),
|
|
|
- this, SLOT(removeLabel())
|
|
|
+ this,
|
|
|
+ SLOT(removeLabel())
|
|
|
+ );
|
|
|
+ connect(
|
|
|
+ button_delete_area_,
|
|
|
+ SIGNAL(clicked()),
|
|
|
+ this,
|
|
|
+ SLOT(deleteArea())
|
|
|
+ );
|
|
|
+ connect(
|
|
|
+ button_change_area_,
|
|
|
+ SIGNAL(clicked()),
|
|
|
+ this,
|
|
|
+ SLOT(focusOnArea())
|
|
|
+ );
|
|
|
+ connect(
|
|
|
+ button_change_area_text_,
|
|
|
+ SIGNAL(clicked()),
|
|
|
+ this,
|
|
|
+ SLOT(editArea())
|
|
|
);
|
|
|
connect(
|
|
|
button_next_image_,
|
|
@@ -533,6 +601,18 @@ ImageLabeler::ImageLabeler(QWidget *aParent, QString aSettingsPath) :
|
|
|
this,
|
|
|
SLOT(clearLabelList())
|
|
|
);
|
|
|
+ connect(
|
|
|
+ button_add_image_,
|
|
|
+ SIGNAL(clicked()),
|
|
|
+ this,
|
|
|
+ SLOT(loadImage())
|
|
|
+ );
|
|
|
+ connect(
|
|
|
+ button_remove_image_,
|
|
|
+ SIGNAL(clicked()),
|
|
|
+ this,
|
|
|
+ SLOT(removeImage())
|
|
|
+ );
|
|
|
connect(
|
|
|
button_confirm_selection_,
|
|
|
SIGNAL(clicked()),
|
|
@@ -691,6 +771,8 @@ ImageLabeler::~ImageLabeler()
|
|
|
delete action_about_;
|
|
|
delete action_help_content_;
|
|
|
|
|
|
+ delete menu_load_;
|
|
|
+ delete menu_save_;
|
|
|
delete menu_pascal_;
|
|
|
delete menu_file_;
|
|
|
delete menu_view_;
|
|
@@ -720,6 +802,9 @@ ImageLabeler::~ImageLabeler()
|
|
|
delete button_add_label_;
|
|
|
delete button_remove_label_;
|
|
|
delete button_bound_box_tool_;
|
|
|
+ delete button_delete_area_;
|
|
|
+ delete button_change_area_;
|
|
|
+ delete button_change_area_text_;
|
|
|
delete button_polygon_tool_;
|
|
|
delete button_tagging_tool_;
|
|
|
delete button_clear_selection_tool_;
|
|
@@ -730,6 +815,7 @@ ImageLabeler::~ImageLabeler()
|
|
|
|
|
|
delete button_confirm_selection_;
|
|
|
|
|
|
+ delete label_list_label_;
|
|
|
delete label_list_areas_;
|
|
|
delete label_toolbox_;
|
|
|
delete label_list_images_;
|
|
@@ -737,12 +823,14 @@ ImageLabeler::~ImageLabeler()
|
|
|
delete list_label_;
|
|
|
delete list_images_widget_;
|
|
|
|
|
|
+ delete layout_imagelist_buttons_;
|
|
|
delete layout_toolbox_;
|
|
|
delete layout_right_;
|
|
|
delete layout_center_buttons_;
|
|
|
delete layout_frame_image_;
|
|
|
delete layout_center_;
|
|
|
delete layout_labelbox_buttons_;
|
|
|
+ delete layout_areabox_buttons_;
|
|
|
delete layout_labelbox_;
|
|
|
delete layout_left_;
|
|
|
delete layout_main_;
|
|
@@ -845,6 +933,8 @@ ImageLabeler::addImage(Image *anImage)
|
|
|
|
|
|
list_images_widget_->addItem(newItem);
|
|
|
list_images_->append(*anImage);
|
|
|
+
|
|
|
+ button_remove_image_->setEnabled(true);
|
|
|
}
|
|
|
|
|
|
//! A slot member creating new label with default parameters
|
|
@@ -1009,13 +1099,8 @@ ImageLabeler::removeLabel()
|
|
|
void
|
|
|
ImageLabeler::removeLabel(int aLabelID)
|
|
|
{
|
|
|
- if (0 == list_label_->count()) {
|
|
|
- return;
|
|
|
- /* NOTREACHED */
|
|
|
- }
|
|
|
-
|
|
|
/* we need to keep BACKGROUND category */
|
|
|
- if (aLabelID < 1) {
|
|
|
+ if (0 == list_label_->count() || aLabelID < 1) {
|
|
|
return;
|
|
|
/* NOTREACHED */
|
|
|
}
|
|
@@ -1162,8 +1247,20 @@ ImageLabeler::editArea()
|
|
|
list_areas_->blockSignals(oldState);
|
|
|
}
|
|
|
|
|
|
-//! \brief A slot member parsing a text of the changed item and tries to edit
|
|
|
-//! the corresponding area
|
|
|
+void
|
|
|
+ImageLabeler::focusOnArea()
|
|
|
+{
|
|
|
+ QListWidgetItem *current = list_areas_->currentItem();
|
|
|
+ if (!current || !list_areas_->count()) {
|
|
|
+ return;
|
|
|
+ /* NOTREACHED */
|
|
|
+ }
|
|
|
+
|
|
|
+ image_holder_->focusOnArea(current);
|
|
|
+}
|
|
|
+
|
|
|
+//! \brief A slot member parsing a text of the changed item
|
|
|
+//! and tries to edit the corresponding area
|
|
|
/*!
|
|
|
* \see polyFromListItemText(QString *aString,int *oldID)
|
|
|
* \see BBoxFromListItemText(QString *aString,int *oldID)
|
|
@@ -1268,8 +1365,9 @@ ImageLabeler::onAreaEdit()
|
|
|
void
|
|
|
ImageLabeler::deleteArea()
|
|
|
{
|
|
|
- if (!deleteArea(list_areas_->currentItem()))
|
|
|
- showWarning(tr("An error occurred while deleting the area"));
|
|
|
+ deleteArea(list_areas_->currentItem());
|
|
|
+ /*if (!deleteArea(list_areas_->currentItem()))
|
|
|
+ showWarning(tr("An error occurred while deleting the area"));*/
|
|
|
}
|
|
|
|
|
|
//! A slot member deleting certain area in the list_areas_ widget
|
|
@@ -1347,6 +1445,13 @@ ImageLabeler::deleteArea(QListWidgetItem *anItem)
|
|
|
image_holder_->update();
|
|
|
|
|
|
unsaved_data_ = 1;
|
|
|
+
|
|
|
+ if (!list_areas_->count()) {
|
|
|
+ button_delete_area_->setEnabled(false);
|
|
|
+ button_change_area_->setEnabled(false);
|
|
|
+ button_change_area_text_->setEnabled(false);
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1657,18 +1762,29 @@ ImageLabeler::saveAllInfo()
|
|
|
|
|
|
objectsToXml(&doc, &root);
|
|
|
|
|
|
- setPureData();
|
|
|
- QDomElement pureData = doc.createElement(tr("pure_data"));
|
|
|
+ /* image size */
|
|
|
QSize imageSize = image_->size();
|
|
|
- QString pixelValues;
|
|
|
+ QString imageSizeString;
|
|
|
+ imageSizeString.append(QString("%1;%2").
|
|
|
+ arg(imageSize.width()).
|
|
|
+ arg(imageSize.height()));
|
|
|
+
|
|
|
+ QDomElement imageSizeElement = doc.createElement(tr("image_size"));
|
|
|
+ QDomText imageSizeText = doc.createTextNode(imageSizeString);
|
|
|
+ imageSizeElement.appendChild(imageSizeText);
|
|
|
+ root.appendChild(imageSizeElement);
|
|
|
|
|
|
+ /* pure data */
|
|
|
+ setPureData();
|
|
|
+ QString pixelValues;
|
|
|
for (int i = 0; i < imageSize.height(); i++) {
|
|
|
for (int j = 0; j < imageSize.width(); j++) {
|
|
|
- pixelValues.append(QString("%1").arg(pure_data_[i][j]));
|
|
|
+ pixelValues.append(QString("%1;").arg(pure_data_[i][j]));
|
|
|
}
|
|
|
pixelValues.append("\n");
|
|
|
}
|
|
|
|
|
|
+ QDomElement pureData = doc.createElement(tr("pure_data"));
|
|
|
QDomText pureDataText = doc.createTextNode(pixelValues);
|
|
|
pureData.appendChild(pureDataText);
|
|
|
root.appendChild(pureData);
|
|
@@ -2019,6 +2135,10 @@ ImageLabeler::loadInfo(QString filename)
|
|
|
QDomNode subNode = element.firstChild();
|
|
|
QDomElement subElement;
|
|
|
|
|
|
+ button_delete_area_->setEnabled(false);
|
|
|
+ button_change_area_->setEnabled(false);
|
|
|
+ button_change_area_text_->setEnabled(false);
|
|
|
+
|
|
|
while(!subNode.isNull()) {
|
|
|
subElement = subNode.toElement();
|
|
|
|
|
@@ -2041,13 +2161,22 @@ ImageLabeler::loadInfo(QString filename)
|
|
|
|
|
|
string = subElement.text();
|
|
|
|
|
|
- if (subElement.tagName() == "bbox") {
|
|
|
+ if (subElement.tagName() == "bbox")
|
|
|
addBBoxFromData(&string, &id);
|
|
|
- }
|
|
|
- if (subElement.tagName() == "poly") {
|
|
|
+ else if (subElement.tagName() == "poly")
|
|
|
addPolyFromData(&string, &id);
|
|
|
+ else {
|
|
|
+ qDebug() <<
|
|
|
+ "loadInfo: "
|
|
|
+ "poly id format is corrupted";
|
|
|
+ subNode = subNode.nextSibling();
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
+ button_delete_area_->setEnabled(true);
|
|
|
+ button_change_area_->setEnabled(true);
|
|
|
+ button_change_area_text_->setEnabled(true);
|
|
|
+
|
|
|
subNode = subNode.nextSibling();
|
|
|
}
|
|
|
}
|
|
@@ -3429,6 +3558,9 @@ ImageLabeler::confirmSelection()
|
|
|
break;
|
|
|
}
|
|
|
button_confirm_selection_->setEnabled(false);
|
|
|
+ button_delete_area_->setEnabled(true);
|
|
|
+ button_change_area_->setEnabled(true);
|
|
|
+ button_change_area_text_->setEnabled(true);
|
|
|
|
|
|
unsaved_data_ = 1;
|
|
|
}
|
|
@@ -3522,6 +3654,7 @@ ImageLabeler::enableTools()
|
|
|
action_save_legend_->setEnabled(true);
|
|
|
action_bound_box_tool_->setEnabled(true);
|
|
|
action_polygon_tool_->setEnabled(true);
|
|
|
+ action_tagging_tool_->setEnabled(true);
|
|
|
action_add_description_->setEnabled(true);
|
|
|
action_undo_->setEnabled(true);
|
|
|
action_redo_->setEnabled(true);
|
|
@@ -3549,6 +3682,7 @@ ImageLabeler::disableTools()
|
|
|
action_save_legend_->setEnabled(false);
|
|
|
action_bound_box_tool_->setEnabled(false);
|
|
|
action_polygon_tool_->setEnabled(false);
|
|
|
+ action_tagging_tool_->setEnabled(false);
|
|
|
button_tagging_tool_->setEnabled(false);
|
|
|
action_add_description_->setEnabled(false);
|
|
|
action_undo_->setEnabled(false);
|
|
@@ -3838,8 +3972,8 @@ ImageLabeler::selectImage(QListWidgetItem *anItem)
|
|
|
/* NOTREACHED */
|
|
|
}
|
|
|
clearAllTool();
|
|
|
- clearLabelList();
|
|
|
- clearLabelColorList();
|
|
|
+ //clearLabelList();
|
|
|
+ //clearLabelColorList();
|
|
|
|
|
|
image_ID_ = list_images_widget_->row(anItem);
|
|
|
|
|
@@ -3865,10 +3999,13 @@ ImageLabeler::selectImage(int anImageID)
|
|
|
/* NOTREACHED */
|
|
|
}
|
|
|
|
|
|
+ action_view_segmented_->setEnabled(false);
|
|
|
+
|
|
|
/* checking if it was labeled before */
|
|
|
if (list_images_->at(anImageID).labeled_ &&
|
|
|
!list_images_->at(anImageID).pas_)
|
|
|
{
|
|
|
+ list_label_colors_.clear();
|
|
|
list_label_->clear();
|
|
|
QString labeled =
|
|
|
alterFileName(list_images_->at(anImageID).image_, "_labeled");
|
|
@@ -3904,7 +4041,16 @@ ImageLabeler::selectImage(int anImageID)
|
|
|
void
|
|
|
ImageLabeler::removeImage()
|
|
|
{
|
|
|
+ int imageCount = list_images_widget_->count();
|
|
|
int num = list_images_widget_->currentRow();
|
|
|
+
|
|
|
+ if (!imageCount || num < 0 || imageCount <= num ||
|
|
|
+ list_images_->count() != imageCount)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ /* NOTREACHED */
|
|
|
+ }
|
|
|
+
|
|
|
list_images_widget_->takeItem(num);
|
|
|
list_images_->takeAt(num);
|
|
|
|
|
@@ -3913,6 +4059,9 @@ ImageLabeler::removeImage()
|
|
|
newStr.prepend(QString("%1: ").arg(i));
|
|
|
list_images_widget_->item(i)->setText(newStr);
|
|
|
}
|
|
|
+
|
|
|
+ if (1 == imageCount)
|
|
|
+ button_remove_image_->setEnabled(false);
|
|
|
}
|
|
|
|
|
|
//! A protected member which is being automatically called on every image resize
|
|
@@ -3992,6 +4141,26 @@ ImageLabeler::keyPressEvent(QKeyEvent *anEvent)
|
|
|
image_holder_->redo();
|
|
|
}
|
|
|
|
|
|
+ if (Qt::Key_Delete == anEvent->key() &&
|
|
|
+ list_areas_->hasFocus()) {
|
|
|
+ deleteArea();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Qt::Key_Delete == anEvent->key() &&
|
|
|
+ list_label_->hasFocus()) {
|
|
|
+ removeLabel();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Qt::Key_Delete == anEvent->key() &&
|
|
|
+ list_images_widget_->hasFocus()) {
|
|
|
+ removeImage();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Qt::Key_Delete == anEvent->key() &&
|
|
|
+ image_holder_->hasFocus()) {
|
|
|
+ image_holder_->removeSelectedPoint();
|
|
|
+ }
|
|
|
+
|
|
|
QWidget::keyPressEvent(anEvent);
|
|
|
}
|
|
|
|
|
@@ -4033,6 +4202,8 @@ ImageLabeler::closeEvent(QCloseEvent *anEvent)
|
|
|
{
|
|
|
Q_UNUSED(anEvent)
|
|
|
writeSettings();
|
|
|
+
|
|
|
+ askForUnsavedData();
|
|
|
}
|
|
|
|
|
|
/*
|