00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "ImageLayer.h"
00017
00018 #include "data/model/Model.h"
00019 #include "base/RealTime.h"
00020 #include "base/Profiler.h"
00021 #include "view/View.h"
00022
00023 #include "data/model/ImageModel.h"
00024 #include "data/fileio/FileSource.h"
00025
00026 #include "widgets/ImageDialog.h"
00027
00028 #include <QPainter>
00029 #include <QMouseEvent>
00030 #include <QInputDialog>
00031 #include <QMutexLocker>
00032 #include <QTextStream>
00033 #include <QMessageBox>
00034
00035 #include <iostream>
00036 #include <cmath>
00037
00038 ImageLayer::ImageMap
00039 ImageLayer::m_images;
00040
00041 QMutex
00042 ImageLayer::m_imageMapMutex;
00043
00044 ImageLayer::ImageLayer() :
00045 Layer(),
00046 m_model(0),
00047 m_editing(false),
00048 m_originalPoint(0, "", ""),
00049 m_editingPoint(0, "", ""),
00050 m_editingCommand(0)
00051 {
00052 }
00053
00054 ImageLayer::~ImageLayer()
00055 {
00056 for (FileSourceMap::iterator i = m_remoteFiles.begin();
00057 i != m_remoteFiles.end(); ++i) {
00058 delete i->second;
00059 }
00060 }
00061
00062 void
00063 ImageLayer::setModel(ImageModel *model)
00064 {
00065 if (m_model == model) return;
00066 m_model = model;
00067
00068 connectSignals(m_model);
00069
00070 emit modelReplaced();
00071 }
00072
00073 Layer::PropertyList
00074 ImageLayer::getProperties() const
00075 {
00076 return Layer::getProperties();
00077 }
00078
00079 QString
00080 ImageLayer::getPropertyLabel(const PropertyName &name) const
00081 {
00082 return "";
00083 }
00084
00085 Layer::PropertyType
00086 ImageLayer::getPropertyType(const PropertyName &name) const
00087 {
00088 return Layer::getPropertyType(name);
00089 }
00090
00091 int
00092 ImageLayer::getPropertyRangeAndValue(const PropertyName &name,
00093 int *min, int *max, int *deflt) const
00094 {
00095 return Layer::getPropertyRangeAndValue(name, min, max, deflt);
00096 }
00097
00098 QString
00099 ImageLayer::getPropertyValueLabel(const PropertyName &name,
00100 int value) const
00101 {
00102 return Layer::getPropertyValueLabel(name, value);
00103 }
00104
00105 void
00106 ImageLayer::setProperty(const PropertyName &name, int value)
00107 {
00108 Layer::setProperty(name, value);
00109 }
00110
00111 bool
00112 ImageLayer::getValueExtents(float &, float &, bool &, QString &) const
00113 {
00114 return false;
00115 }
00116
00117 bool
00118 ImageLayer::isLayerScrollable(const View *v) const
00119 {
00120 return true;
00121 }
00122
00123
00124 ImageModel::PointList
00125 ImageLayer::getLocalPoints(View *v, int x, int y) const
00126 {
00127 if (!m_model) return ImageModel::PointList();
00128
00129
00130 const ImageModel::PointList &points(m_model->getPoints());
00131
00132 ImageModel::PointList rv;
00133
00134 for (ImageModel::PointList::const_iterator i = points.begin();
00135 i != points.end(); ) {
00136
00137 const ImageModel::Point &p(*i);
00138 int px = v->getXForFrame(p.frame);
00139 if (px > x) break;
00140
00141 ++i;
00142 if (i != points.end()) {
00143 int nx = v->getXForFrame((*i).frame);
00144 if (nx < x) {
00145
00146
00147
00148 continue;
00149 }
00150 }
00151
00152
00153
00154 int width = 32;
00155 if (m_scaled[v].find(p.image) != m_scaled[v].end()) {
00156 width = m_scaled[v][p.image].width();
00157
00158 }
00159
00160 if (x >= px && x < px + width) {
00161 rv.insert(p);
00162 }
00163 }
00164
00165
00166
00167 return rv;
00168 }
00169
00170 QString
00171 ImageLayer::getFeatureDescription(View *v, QPoint &pos) const
00172 {
00173 int x = pos.x();
00174
00175 if (!m_model || !m_model->getSampleRate()) return "";
00176
00177 ImageModel::PointList points = getLocalPoints(v, x, pos.y());
00178
00179 if (points.empty()) {
00180 if (!m_model->isReady()) {
00181 return tr("In progress");
00182 } else {
00183 return "";
00184 }
00185 }
00186
00187 long useFrame = points.begin()->frame;
00188
00189 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
00190
00191 QString text;
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 return text;
00204 }
00205
00206
00208
00209 bool
00210 ImageLayer::snapToFeatureFrame(View *v, int &frame,
00211 size_t &resolution,
00212 SnapType snap) const
00213 {
00214 if (!m_model) {
00215 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
00216 }
00217
00218 resolution = m_model->getResolution();
00219 ImageModel::PointList points;
00220
00221 if (snap == SnapNeighbouring) {
00222
00223 points = getLocalPoints(v, v->getXForFrame(frame), -1);
00224 if (points.empty()) return false;
00225 frame = points.begin()->frame;
00226 return true;
00227 }
00228
00229 points = m_model->getPoints(frame, frame);
00230 int snapped = frame;
00231 bool found = false;
00232
00233 for (ImageModel::PointList::const_iterator i = points.begin();
00234 i != points.end(); ++i) {
00235
00236 if (snap == SnapRight) {
00237
00238 if (i->frame > frame) {
00239 snapped = i->frame;
00240 found = true;
00241 break;
00242 }
00243
00244 } else if (snap == SnapLeft) {
00245
00246 if (i->frame <= frame) {
00247 snapped = i->frame;
00248 found = true;
00249 } else {
00250 break;
00251 }
00252
00253 } else {
00254
00255 ImageModel::PointList::const_iterator j = i;
00256 ++j;
00257
00258 if (j == points.end()) {
00259
00260 snapped = i->frame;
00261 found = true;
00262 break;
00263
00264 } else if (j->frame >= frame) {
00265
00266 if (j->frame - frame < frame - i->frame) {
00267 snapped = j->frame;
00268 } else {
00269 snapped = i->frame;
00270 }
00271 found = true;
00272 break;
00273 }
00274 }
00275 }
00276
00277 frame = snapped;
00278 return found;
00279 }
00280
00281 void
00282 ImageLayer::paint(View *v, QPainter &paint, QRect rect) const
00283 {
00284 if (!m_model || !m_model->isOK()) return;
00285
00286 int sampleRate = m_model->getSampleRate();
00287 if (!sampleRate) return;
00288
00289
00290
00291
00292 int x0 = 0, x1 = v->width();
00293
00294 long frame0 = v->getFrameForX(x0);
00295 long frame1 = v->getFrameForX(x1);
00296
00297 ImageModel::PointList points(m_model->getPoints(frame0, frame1));
00298 if (points.empty()) return;
00299
00300 paint.save();
00301 paint.setClipRect(rect.x(), 0, rect.width(), v->height());
00302
00303 QColor penColour;
00304 penColour = v->getForeground();
00305
00306 QColor brushColour;
00307 brushColour = v->getBackground();
00308
00309 int h, s, val;
00310 brushColour.getHsv(&h, &s, &val);
00311 brushColour.setHsv(h, s, 255, 240);
00312
00313 paint.setPen(penColour);
00314 paint.setBrush(brushColour);
00315 paint.setRenderHint(QPainter::Antialiasing, true);
00316
00317 for (ImageModel::PointList::const_iterator i = points.begin();
00318 i != points.end(); ++i) {
00319
00320 const ImageModel::Point &p(*i);
00321
00322 int x = v->getXForFrame(p.frame);
00323
00324 int nx = x + 2000;
00325 ImageModel::PointList::const_iterator j = i;
00326 ++j;
00327 if (j != points.end()) {
00328 int jx = v->getXForFrame(j->frame);
00329 if (jx < nx) nx = jx;
00330 }
00331
00332 drawImage(v, paint, p, x, nx);
00333 }
00334
00335 paint.setRenderHint(QPainter::Antialiasing, false);
00336 paint.restore();
00337 }
00338
00339 void
00340 ImageLayer::drawImage(View *v, QPainter &paint, const ImageModel::Point &p,
00341 int x, int nx) const
00342 {
00343 QString label = p.label;
00344 QString imageName = p.image;
00345
00346 QImage image;
00347 QString additionalText;
00348
00349 QSize imageSize;
00350 if (!getImageOriginalSize(imageName, imageSize)) {
00351 image = QImage(":icons/emptypage.png");
00352 imageSize = image.size();
00353 additionalText = imageName;
00354 }
00355
00356 int topMargin = 10;
00357 int bottomMargin = 10;
00358 int spacing = 5;
00359
00360 if (v->height() < 100) {
00361 topMargin = 5;
00362 bottomMargin = 5;
00363 }
00364
00365 int maxBoxHeight = v->height() - topMargin - bottomMargin;
00366
00367 int availableWidth = nx - x - 3;
00368 if (availableWidth < 20) availableWidth = 20;
00369
00370 QRect labelRect;
00371
00372 if (label != "") {
00373
00374 int likelyHeight = v->height() / 4;
00375
00376 int likelyWidth =
00377 ((maxBoxHeight - likelyHeight) * imageSize.width())
00378 / imageSize.height();
00379
00380 if (likelyWidth > imageSize.width()) {
00381 likelyWidth = imageSize.width();
00382 }
00383
00384 if (likelyWidth > availableWidth) {
00385 likelyWidth = availableWidth;
00386 }
00387
00388 int singleWidth = paint.fontMetrics().width(label);
00389 if (singleWidth < availableWidth && singleWidth < likelyWidth * 2) {
00390 likelyWidth = singleWidth + 4;
00391 }
00392
00393 labelRect = paint.fontMetrics().boundingRect
00394 (QRect(0, 0, likelyWidth, likelyHeight),
00395 Qt::AlignCenter | Qt::TextWordWrap, label);
00396
00397 labelRect.setWidth(labelRect.width() + 6);
00398 }
00399
00400 if (image.isNull()) {
00401 image = getImage(v, imageName,
00402 QSize(availableWidth,
00403 maxBoxHeight - labelRect.height()));
00404 }
00405
00406 int boxWidth = image.width();
00407 if (boxWidth < labelRect.width()) {
00408 boxWidth = labelRect.width();
00409 }
00410
00411 int boxHeight = image.height();
00412 if (label != "") {
00413 boxHeight += labelRect.height() + spacing;
00414 }
00415
00416 int division = image.height();
00417
00418 if (additionalText != "") {
00419
00420 paint.save();
00421
00422 QFont font(paint.font());
00423 font.setItalic(true);
00424 paint.setFont(font);
00425
00426 int tw = paint.fontMetrics().width(additionalText);
00427 if (tw > availableWidth) {
00428 tw = availableWidth;
00429 }
00430 if (boxWidth < tw) {
00431 boxWidth = tw;
00432 }
00433 boxHeight += paint.fontMetrics().height();
00434 division += paint.fontMetrics().height();
00435 }
00436
00437 bottomMargin = v->height() - topMargin - boxHeight;
00438 if (bottomMargin > topMargin + v->height()/7) {
00439 topMargin += v->height()/8;
00440 bottomMargin -= v->height()/8;
00441 }
00442
00443 paint.drawRect(x - 1,
00444 topMargin - 1,
00445 boxWidth + 2,
00446 boxHeight + 2);
00447
00448 int imageY;
00449 if (label != "") {
00450 imageY = topMargin + labelRect.height() + spacing;
00451 } else {
00452 imageY = topMargin;
00453 }
00454
00455 paint.drawImage(x + (boxWidth - image.width())/2,
00456 imageY,
00457 image);
00458
00459 if (additionalText != "") {
00460 paint.drawText(x,
00461 imageY + image.height() + paint.fontMetrics().ascent(),
00462 additionalText);
00463 paint.restore();
00464 }
00465
00466 if (label != "") {
00467 paint.drawLine(x,
00468 topMargin + labelRect.height() + spacing,
00469 x + boxWidth,
00470 topMargin + labelRect.height() + spacing);
00471
00472 paint.drawText(QRect(x,
00473 topMargin,
00474 boxWidth,
00475 labelRect.height()),
00476 Qt::AlignCenter | Qt::TextWordWrap,
00477 label);
00478 }
00479 }
00480
00481 void
00482 ImageLayer::setLayerDormant(const View *v, bool dormant)
00483 {
00484 if (dormant) {
00485
00486
00487
00488 QMutexLocker locker(&m_imageMapMutex);
00489 for (ImageMap::iterator i = m_scaled[v].begin();
00490 i != m_scaled[v].end(); ++i) {
00491 m_images.erase(i->first);
00492 }
00493 m_scaled.erase(v);
00494 }
00495 }
00496
00498
00499 bool
00500 ImageLayer::getImageOriginalSize(QString name, QSize &size) const
00501 {
00502
00503
00504 QMutexLocker locker(&m_imageMapMutex);
00505 if (m_images.find(name) == m_images.end()) {
00506
00507 m_images[name] = QImage(getLocalFilename(name));
00508 }
00509 if (m_images[name].isNull()) {
00510
00511 return false;
00512 } else {
00513 size = m_images[name].size();
00514 return true;
00515 }
00516 }
00517
00518 QImage
00519 ImageLayer::getImage(View *v, QString name, QSize maxSize) const
00520 {
00521 bool need = false;
00522
00523
00524
00525
00526 if (!m_scaled[v][name].isNull() &&
00527 ((m_scaled[v][name].width() == maxSize.width() &&
00528 m_scaled[v][name].height() <= maxSize.height()) ||
00529 (m_scaled[v][name].width() <= maxSize.width() &&
00530 m_scaled[v][name].height() == maxSize.height()))) {
00531
00532 return m_scaled[v][name];
00533 }
00534
00535 QMutexLocker locker(&m_imageMapMutex);
00536
00537 if (m_images.find(name) == m_images.end()) {
00538 m_images[name] = QImage(getLocalFilename(name));
00539 }
00540
00541 if (m_images[name].isNull()) {
00542
00543 m_scaled[v][name] = QImage();
00544 } else if (m_images[name].width() <= maxSize.width() &&
00545 m_images[name].height() <= maxSize.height()) {
00546 m_scaled[v][name] = m_images[name];
00547 } else {
00548 m_scaled[v][name] =
00549 m_images[name].scaled(maxSize,
00550 Qt::KeepAspectRatio,
00551 Qt::SmoothTransformation);
00552 }
00553
00554 return m_scaled[v][name];
00555 }
00556
00557 void
00558 ImageLayer::drawStart(View *v, QMouseEvent *e)
00559 {
00560
00561
00562 if (!m_model) {
00563 std::cerr << "ImageLayer::drawStart: no model" << std::endl;
00564 return;
00565 }
00566
00567 long frame = v->getFrameForX(e->x());
00568 if (frame < 0) frame = 0;
00569 frame = frame / m_model->getResolution() * m_model->getResolution();
00570
00571 m_editingPoint = ImageModel::Point(frame, "", "");
00572 m_originalPoint = m_editingPoint;
00573
00574 if (m_editingCommand) m_editingCommand->finish();
00575 m_editingCommand = new ImageModel::EditCommand(m_model, "Add Image");
00576 m_editingCommand->addPoint(m_editingPoint);
00577
00578 m_editing = true;
00579 }
00580
00581 void
00582 ImageLayer::drawDrag(View *v, QMouseEvent *e)
00583 {
00584
00585
00586 if (!m_model || !m_editing) return;
00587
00588 long frame = v->getFrameForX(e->x());
00589 if (frame < 0) frame = 0;
00590 frame = frame / m_model->getResolution() * m_model->getResolution();
00591
00592 m_editingCommand->deletePoint(m_editingPoint);
00593 m_editingPoint.frame = frame;
00594 m_editingCommand->addPoint(m_editingPoint);
00595 }
00596
00597 void
00598 ImageLayer::drawEnd(View *v, QMouseEvent *)
00599 {
00600
00601 if (!m_model || !m_editing) return;
00602
00603 bool ok = false;
00604
00605 ImageDialog dialog(tr("Select image"), "", "");
00606
00607 if (dialog.exec() == QDialog::Accepted) {
00608
00609 checkAddRemote(dialog.getImage());
00610
00611 ImageModel::ChangeImageCommand *command =
00612 new ImageModel::ChangeImageCommand
00613 (m_model, m_editingPoint, dialog.getImage(), dialog.getLabel());
00614 m_editingCommand->addCommand(command);
00615 } else {
00616 m_editingCommand->deletePoint(m_editingPoint);
00617 }
00618
00619 m_editingCommand->finish();
00620 m_editingCommand = 0;
00621 m_editing = false;
00622 }
00623
00624 bool
00625 ImageLayer::addImage(long frame, QString url)
00626 {
00627 QImage image(getLocalFilename(url));
00628 if (image.isNull()) {
00629 delete m_remoteFiles[url];
00630 m_remoteFiles.erase(url);
00631 return false;
00632 }
00633
00634 ImageModel::Point point(frame, url, "");
00635 ImageModel::EditCommand *command =
00636 new ImageModel::EditCommand(m_model, "Add Image");
00637 command->addPoint(point);
00638 command->finish();
00639 return true;
00640 }
00641
00642 void
00643 ImageLayer::editStart(View *v, QMouseEvent *e)
00644 {
00645
00646
00647 if (!m_model) return;
00648
00649 ImageModel::PointList points = getLocalPoints(v, e->x(), e->y());
00650 if (points.empty()) return;
00651
00652 m_editOrigin = e->pos();
00653 m_editingPoint = *points.begin();
00654 m_originalPoint = m_editingPoint;
00655
00656 if (m_editingCommand) {
00657 m_editingCommand->finish();
00658 m_editingCommand = 0;
00659 }
00660
00661 m_editing = true;
00662 }
00663
00664 void
00665 ImageLayer::editDrag(View *v, QMouseEvent *e)
00666 {
00667 if (!m_model || !m_editing) return;
00668
00669 long frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x());
00670 long frame = m_originalPoint.frame + frameDiff;
00671
00672 if (frame < 0) frame = 0;
00673 frame = (frame / m_model->getResolution()) * m_model->getResolution();
00674
00675 if (!m_editingCommand) {
00676 m_editingCommand = new ImageModel::EditCommand(m_model, tr("Move Image"));
00677 }
00678
00679 m_editingCommand->deletePoint(m_editingPoint);
00680 m_editingPoint.frame = frame;
00681 m_editingCommand->addPoint(m_editingPoint);
00682 }
00683
00684 void
00685 ImageLayer::editEnd(View *, QMouseEvent *)
00686 {
00687
00688 if (!m_model || !m_editing) return;
00689
00690 if (m_editingCommand) {
00691 m_editingCommand->finish();
00692 }
00693
00694 m_editingCommand = 0;
00695 m_editing = false;
00696 }
00697
00698 bool
00699 ImageLayer::editOpen(View *v, QMouseEvent *e)
00700 {
00701 if (!m_model) return false;
00702
00703 ImageModel::PointList points = getLocalPoints(v, e->x(), e->y());
00704 if (points.empty()) return false;
00705
00706 QString image = points.begin()->image;
00707 QString label = points.begin()->label;
00708
00709 ImageDialog dialog(tr("Select image"),
00710 image,
00711 label);
00712
00713 if (dialog.exec() == QDialog::Accepted) {
00714
00715 checkAddRemote(dialog.getImage());
00716
00717 ImageModel::ChangeImageCommand *command =
00718 new ImageModel::ChangeImageCommand
00719 (m_model, *points.begin(), dialog.getImage(), dialog.getLabel());
00720
00721 CommandHistory::getInstance()->addCommand(command);
00722 }
00723
00724 return true;
00725 }
00726
00727 void
00728 ImageLayer::moveSelection(Selection s, size_t newStartFrame)
00729 {
00730 if (!m_model) return;
00731
00732 ImageModel::EditCommand *command =
00733 new ImageModel::EditCommand(m_model, tr("Drag Selection"));
00734
00735 ImageModel::PointList points =
00736 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
00737
00738 for (ImageModel::PointList::iterator i = points.begin();
00739 i != points.end(); ++i) {
00740
00741 if (s.contains(i->frame)) {
00742 ImageModel::Point newPoint(*i);
00743 newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
00744 command->deletePoint(*i);
00745 command->addPoint(newPoint);
00746 }
00747 }
00748
00749 command->finish();
00750 }
00751
00752 void
00753 ImageLayer::resizeSelection(Selection s, Selection newSize)
00754 {
00755 if (!m_model) return;
00756
00757 ImageModel::EditCommand *command =
00758 new ImageModel::EditCommand(m_model, tr("Resize Selection"));
00759
00760 ImageModel::PointList points =
00761 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
00762
00763 double ratio =
00764 double(newSize.getEndFrame() - newSize.getStartFrame()) /
00765 double(s.getEndFrame() - s.getStartFrame());
00766
00767 for (ImageModel::PointList::iterator i = points.begin();
00768 i != points.end(); ++i) {
00769
00770 if (s.contains(i->frame)) {
00771
00772 double target = i->frame;
00773 target = newSize.getStartFrame() +
00774 double(target - s.getStartFrame()) * ratio;
00775
00776 ImageModel::Point newPoint(*i);
00777 newPoint.frame = lrint(target);
00778 command->deletePoint(*i);
00779 command->addPoint(newPoint);
00780 }
00781 }
00782
00783 command->finish();
00784 }
00785
00786 void
00787 ImageLayer::deleteSelection(Selection s)
00788 {
00789 if (!m_model) return;
00790
00791 ImageModel::EditCommand *command =
00792 new ImageModel::EditCommand(m_model, tr("Delete Selection"));
00793
00794 ImageModel::PointList points =
00795 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
00796
00797 for (ImageModel::PointList::iterator i = points.begin();
00798 i != points.end(); ++i) {
00799 if (s.contains(i->frame)) command->deletePoint(*i);
00800 }
00801
00802 command->finish();
00803 }
00804
00805 void
00806 ImageLayer::copy(View *v, Selection s, Clipboard &to)
00807 {
00808 if (!m_model) return;
00809
00810 ImageModel::PointList points =
00811 m_model->getPoints(s.getStartFrame(), s.getEndFrame());
00812
00813 for (ImageModel::PointList::iterator i = points.begin();
00814 i != points.end(); ++i) {
00815 if (s.contains(i->frame)) {
00816 Clipboard::Point point(i->frame, i->label);
00817 point.setReferenceFrame(alignToReference(v, i->frame));
00818 to.addPoint(point);
00819 }
00820 }
00821 }
00822
00823 bool
00824 ImageLayer::paste(View *v, const Clipboard &from, int frameOffset, bool )
00825 {
00826 if (!m_model) return false;
00827
00828 const Clipboard::PointList &points = from.getPoints();
00829
00830 bool realign = false;
00831
00832 if (clipboardHasDifferentAlignment(v, from)) {
00833
00834 QMessageBox::StandardButton button =
00835 QMessageBox::question(v, tr("Re-align pasted items?"),
00836 tr("The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"),
00837 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
00838 QMessageBox::Yes);
00839
00840 if (button == QMessageBox::Cancel) {
00841 return false;
00842 }
00843
00844 if (button == QMessageBox::Yes) {
00845 realign = true;
00846 }
00847 }
00848
00849 ImageModel::EditCommand *command =
00850 new ImageModel::EditCommand(m_model, tr("Paste"));
00851
00852 for (Clipboard::PointList::const_iterator i = points.begin();
00853 i != points.end(); ++i) {
00854
00855 if (!i->haveFrame()) continue;
00856
00857 size_t frame = 0;
00858
00859 if (!realign) {
00860
00861 frame = i->getFrame();
00862
00863 } else {
00864
00865 if (i->haveReferenceFrame()) {
00866 frame = i->getReferenceFrame();
00867 frame = alignFromReference(v, frame);
00868 } else {
00869 frame = i->getFrame();
00870 }
00871 }
00872
00873 ImageModel::Point newPoint(frame);
00874
00876
00877 if (i->haveLabel()) {
00878 newPoint.label = i->getLabel();
00879 } else if (i->haveValue()) {
00880 newPoint.label = QString("%1").arg(i->getValue());
00881 } else {
00882 newPoint.label = tr("New Point");
00883 }
00884
00885 command->addPoint(newPoint);
00886 }
00887
00888 command->finish();
00889 return true;
00890 }
00891
00892 QString
00893 ImageLayer::getLocalFilename(QString img) const
00894 {
00895 if (m_remoteFiles.find(img) == m_remoteFiles.end()) {
00896 checkAddRemote(img);
00897 if (m_remoteFiles.find(img) == m_remoteFiles.end()) {
00898 return img;
00899 }
00900 }
00901 return m_remoteFiles[img]->getLocalFilename();
00902 }
00903
00904 void
00905 ImageLayer::checkAddRemote(QString img) const
00906 {
00907 if (FileSource::isRemote(img)) {
00908
00909 std::cerr << "ImageLayer::checkAddRemote(" << img.toStdString() << "): yes, trying..." << std::endl;
00910
00911 if (m_remoteFiles.find(img) != m_remoteFiles.end()) {
00912 return;
00913 }
00914
00915 FileSource *rf = new FileSource(img, FileSource::ProgressDialog);
00916 if (rf->isOK()) {
00917 std::cerr << "ok, adding it (local filename = " << rf->getLocalFilename().toStdString() << ")" << std::endl;
00918 m_remoteFiles[img] = rf;
00919 connect(rf, SIGNAL(ready()), this, SLOT(remoteFileReady()));
00920 } else {
00921 delete rf;
00922 }
00923 }
00924 }
00925
00926 void
00927 ImageLayer::checkAddRemotes()
00928 {
00929 const ImageModel::PointList &points(m_model->getPoints());
00930
00931 for (ImageModel::PointList::const_iterator i = points.begin();
00932 i != points.end(); ++i) {
00933
00934 checkAddRemote((*i).image);
00935 }
00936 }
00937
00938 void
00939 ImageLayer::remoteFileReady()
00940 {
00941
00942
00943 FileSource *rf = dynamic_cast<FileSource *>(sender());
00944 if (!rf) return;
00945
00946 QString img;
00947 for (FileSourceMap::const_iterator i = m_remoteFiles.begin();
00948 i != m_remoteFiles.end(); ++i) {
00949 if (i->second == rf) {
00950 img = i->first;
00951
00952 break;
00953 }
00954 }
00955 if (img == "") return;
00956
00957 QMutexLocker locker(&m_imageMapMutex);
00958 m_images.erase(img);
00959 for (ViewImageMap::iterator i = m_scaled.begin(); i != m_scaled.end(); ++i) {
00960 i->second.erase(img);
00961 emit modelChanged();
00962 }
00963 }
00964
00965 void
00966 ImageLayer::toXml(QTextStream &stream,
00967 QString indent, QString extraAttributes) const
00968 {
00969 Layer::toXml(stream, indent, extraAttributes);
00970 }
00971
00972 void
00973 ImageLayer::setProperties(const QXmlAttributes &attributes)
00974 {
00975 }
00976