diff --git a/uppsrc/Geom/Ctrl/PlotterCtrl.cpp b/uppsrc/Geom/Ctrl/PlotterCtrl.cpp index 885cfc0fb..0ac50fc7b 100644 --- a/uppsrc/Geom/Ctrl/PlotterCtrl.cpp +++ b/uppsrc/Geom/Ctrl/PlotterCtrl.cpp @@ -1203,12 +1203,31 @@ Image ZoomOutDragDrop::Cursor(Pointf pt, dword keyflags, bool dragging) const } bool ZoomOutDragDrop::Push(Pointf pt, dword keyflags) +{ + return true; +} + +void ZoomOutDragDrop::DropRect(const Rectf& rc, dword keyflags) +{ + Rectf view_rc = owner.GetViewRect(); + Rect screen_rc = owner.ToClient(rc); + Sizef new_scale = (Sizef)max(screen_rc.Size(), Size(10, 10)) / view_rc.Size(); + double aspect = owner.GetAspectRatio(); + if(aspect != 0) + new_scale = max(new_scale, Sizef(new_scale.cy / aspect, new_scale.cx * aspect)); + if(owner.IsReversedX()) new_scale.cx = -new_scale.cx; + if(owner.IsReversedY()) new_scale.cy = -new_scale.cy; + Pointf new_delta = Pointf(screen_rc.CenterPoint()) - new_scale * Sizef(view_rc.CenterPoint()); + owner.SetZoom(new_scale, new_delta); + owner.WhenUserZoom(); +} + +void ZoomOutDragDrop::Click(Pointf pt, dword keyflags) { Rectf rc = GetOwner().GetViewRect(); rc.Inflate(rc.Size() * 0.5); owner.Zoom(rc + pt - rc.CenterPoint()); owner.WhenUserZoom(); - return false; } ////////////////////////////////////////////////////////////////////// diff --git a/uppsrc/Geom/Ctrl/PlotterCtrl.h b/uppsrc/Geom/Ctrl/PlotterCtrl.h index 789052758..6da8a699c 100644 --- a/uppsrc/Geom/Ctrl/PlotterCtrl.h +++ b/uppsrc/Geom/Ctrl/PlotterCtrl.h @@ -125,6 +125,10 @@ public: double GetAvgScale() const; Pointf GetDelta() const { return delta; } Pointf GetPushDelta() const { return push_delta; } + + bool IsReversedX() const { return rev_x; } + bool IsReversedY() const { return rev_y; } + bool IsReversing() const { return scale.cx * scale.cy < 0; } Sizef GetPhysicalZoom() const; @@ -320,6 +324,8 @@ public: virtual Image Cursor(Pointf pt, dword keyflags, bool dragging) const; virtual bool Push(Pointf pt, dword keyflags); + virtual void DropRect(const Rectf& rc, dword keyflags); + virtual void Click(Pointf pt, dword keyflags); private: PlotterCtrl& owner; diff --git a/uppsrc/Oracle/Oci8.cpp b/uppsrc/Oracle/Oci8.cpp index 65edf2c3c..5a987ff54 100644 --- a/uppsrc/Oracle/Oci8.cpp +++ b/uppsrc/Oracle/Oci8.cpp @@ -1491,9 +1491,11 @@ void OracleBlob::Write(int64 at, const void *ptr, dword size) { ASSERT(IsOpen() && (style & STRM_WRITE) && session); ASSERT(at == (dword)at); ub4 n = size; - if(session->oci8.OCILobWrite(session->svchp, session->errhp, locp, &n, (dword)at + 1, (void *)ptr, size, - OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT) != OCI_SUCCESS || n != size) + int res = session->oci8.OCILobWrite(session->svchp, session->errhp, locp, &n, (dword)at + 1, (void *)ptr, size, + OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT); + if(res != OCI_SUCCESS || n != size) { + RLOG("OracleBlob::Write(" << at << ", " << size << "): res = " << res << ", n = " << n); SetError(); } } diff --git a/uppsrc/plugin/jpg/jpgupp.cpp b/uppsrc/plugin/jpg/jpgupp.cpp index f3c2f562f..577079574 100644 --- a/uppsrc/plugin/jpg/jpgupp.cpp +++ b/uppsrc/plugin/jpg/jpgupp.cpp @@ -26,6 +26,17 @@ enum ROW_BUF_SIZE = 16384, }; +enum { + EXIF_BYTE = 1, // An 8-bit unsigned integer + EXIF_ASCII = 2, // An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL + EXIF_SHORT = 3, // A 16-bit (2-byte) unsigned integer + EXIF_LONG = 4, // A 32-bit (4-byte) unsigned integer + EXIF_RATIONAL = 5, // Two LONGs. The first LONG is the numerator and the second LONG expresses the denominator + EXIF_UNDEFINED = 7, // An 8-bit byte that can take any value depending on the field definition + EXIF_SLONG = 9, // A 32-bit (4-byte) signed integer (2's complement notation) + EXIF_SRATIONAL = 10, // Two SLONGs. The first SLONG is the numerator and the second SLONG is the denominator +}; + struct jpg_stream_destination_mgr { jpeg_destination_mgr pub; @@ -336,13 +347,17 @@ int JPGRaster::Data::ExifDir(const char *begin, int offset, IFD_TYPE type) } } else if(type == GPS_IFD) { - if((tag == 2 || tag == 4) && fmt == 5 && count == 3) { + if((tag == 2 || tag == 4) && fmt == EXIF_RATIONAL && count == 3) { metadata.Add(tag == 2 ? "GPSLatitude" : "GPSLongitude", ExifF5(data + 0) + ExifF5(data + 8) / 60 + ExifF5(data + 16) / 3600); // puts(NFormat("GPSLatitude: %n %n %n", n1, n2, n3)); } - else if(tag == 6 && fmt == 5 && count == 1) + else if(tag == 6 && fmt == EXIF_RATIONAL && count == 1) metadata.Add("GPSAltitude", ExifF5(data)); + else if(tag == 16 && fmt == EXIF_ASCII && count == 2 && *data) + metadata.Add("GPSImgDirectionRef", String(*data, 1)); + else if(tag == 17 && fmt == EXIF_RATIONAL && count == 1) + metadata.Add("GPSImgDirection", ExifF5(data + 0)); } } int nextoff = Exif32(e); diff --git a/uppsrc/plugin/sqlite3/Sqlite3upp.cpp b/uppsrc/plugin/sqlite3/Sqlite3upp.cpp index 88d69ad25..e4746a827 100644 --- a/uppsrc/plugin/sqlite3/Sqlite3upp.cpp +++ b/uppsrc/plugin/sqlite3/Sqlite3upp.cpp @@ -84,6 +84,11 @@ void Sqlite3Connection::BindParam(int i, const Value& r) { if (IsNull(r)) sqlite3_bind_null(current_stmt,i); else switch (r.GetType()) { + case SQLRAW_V: { + SqlRaw p = r; + sqlite3_bind_blob(current_stmt, i, p, p.GetLength(), SQLITE_TRANSIENT); + break; + } case STRING_V: case WSTRING_V: { WString p = r;