Kaydet (Commit) 1ba00c21 authored tarafından Miklos Vajna's avatar Miklos Vajna

lokdocview: handle part number in view selections/cursors

This way we show view selections/cursors from other views only in case
the part number matches. Anything else looks buggy in Calc/Impress.

Change-Id: If3ecbfc4b05350606730319b1a570afc15fd9d0a
Reviewed-on: https://gerrit.libreoffice.org/27315Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst 7127cba6
...@@ -48,6 +48,32 @@ ...@@ -48,6 +48,32 @@
/// This is expected to be locked during setView(), doSomethingElse() LOK calls. /// This is expected to be locked during setView(), doSomethingElse() LOK calls.
std::mutex g_aLOKMutex; std::mutex g_aLOKMutex;
/// Same as a GdkRectangle, but also tracks in which part the rectangle is.
struct ViewRectangle
{
int m_nPart;
GdkRectangle m_aRectangle;
ViewRectangle(int nPart = 0, const GdkRectangle& rRectangle = GdkRectangle())
: m_nPart(nPart),
m_aRectangle(rRectangle)
{
}
};
/// Same as a list of GdkRectangles, but also tracks in which part the rectangle is.
struct ViewRectangles
{
int m_nPart;
std::vector<GdkRectangle> m_aRectangles;
ViewRectangles(int nPart = 0, const std::vector<GdkRectangle>& rRectangles = std::vector<GdkRectangle>())
: m_nPart(nPart),
m_aRectangles(rRectangles)
{
}
};
/// Private struct used by this GObject type /// Private struct used by this GObject type
struct LOKDocViewPrivateImpl struct LOKDocViewPrivateImpl
{ {
...@@ -78,7 +104,7 @@ struct LOKDocViewPrivateImpl ...@@ -78,7 +104,7 @@ struct LOKDocViewPrivateImpl
GdkRectangle m_aVisibleCursor; GdkRectangle m_aVisibleCursor;
/// Position and size of the view cursors. The current view can only see /// Position and size of the view cursors. The current view can only see
/// them, can't modify them. Key is the view id. /// them, can't modify them. Key is the view id.
std::map<int, GdkRectangle> m_aViewCursors; std::map<int, ViewRectangle> m_aViewCursors;
/// Cursor overlay is visible or hidden (for blinking). /// Cursor overlay is visible or hidden (for blinking).
gboolean m_bCursorOverlayVisible; gboolean m_bCursorOverlayVisible;
/// Cursor is visible or hidden (e.g. for graphic selection). /// Cursor is visible or hidden (e.g. for graphic selection).
...@@ -98,7 +124,7 @@ struct LOKDocViewPrivateImpl ...@@ -98,7 +124,7 @@ struct LOKDocViewPrivateImpl
std::vector<GdkRectangle> m_aTextSelectionRectangles; std::vector<GdkRectangle> m_aTextSelectionRectangles;
/// Rectangles of view selections. The current view can only see /// Rectangles of view selections. The current view can only see
/// them, can't modify them. Key is the view id. /// them, can't modify them. Key is the view id.
std::map<int, std::vector<GdkRectangle>> m_aTextViewSelectionRectangles; std::map<int, ViewRectangles> m_aTextViewSelectionRectangles;
/// Position and size of the selection start (as if there would be a cursor caret there). /// Position and size of the selection start (as if there would be a cursor caret there).
GdkRectangle m_aTextSelectionStart; GdkRectangle m_aTextSelectionStart;
/// Position and size of the selection end. /// Position and size of the selection end.
...@@ -106,11 +132,11 @@ struct LOKDocViewPrivateImpl ...@@ -106,11 +132,11 @@ struct LOKDocViewPrivateImpl
GdkRectangle m_aGraphicSelection; GdkRectangle m_aGraphicSelection;
/// Position and size of the graphic view selections. The current view can only /// Position and size of the graphic view selections. The current view can only
/// see them, can't modify them. Key is the view id. /// see them, can't modify them. Key is the view id.
std::map<int, GdkRectangle> m_aGraphicViewSelections; std::map<int, ViewRectangle> m_aGraphicViewSelections;
GdkRectangle m_aCellCursor; GdkRectangle m_aCellCursor;
/// Position and size of the cell view cursors. The current view can only /// Position and size of the cell view cursors. The current view can only
/// see them, can't modify them. Key is the view id. /// see them, can't modify them. Key is the view id.
std::map<int, GdkRectangle> m_aCellViewCursors; std::map<int, ViewRectangle> m_aCellViewCursors;
gboolean m_bInDragGraphicSelection; gboolean m_bInDragGraphicSelection;
/// @name Start/middle/end handle. /// @name Start/middle/end handle.
...@@ -146,6 +172,9 @@ struct LOKDocViewPrivateImpl ...@@ -146,6 +172,9 @@ struct LOKDocViewPrivateImpl
/// View ID, returned by createView() or 0 by default. /// View ID, returned by createView() or 0 by default.
int m_nViewId; int m_nViewId;
/// Part ID, returned by getPart().
int m_nPartId;
/** /**
* Contains a freshly set zoom level: logic size of a tile. * Contains a freshly set zoom level: logic size of a tile.
* It gets reset back to 0 when LOK was informed about this zoom change. * It gets reset back to 0 when LOK was informed about this zoom change.
...@@ -197,6 +226,7 @@ struct LOKDocViewPrivateImpl ...@@ -197,6 +226,7 @@ struct LOKDocViewPrivateImpl
m_aHandleEndRect({0, 0, 0, 0}), m_aHandleEndRect({0, 0, 0, 0}),
m_bInDragEndHandle(false), m_bInDragEndHandle(false),
m_nViewId(0), m_nViewId(0),
m_nPartId(0),
m_nTileSizeTwips(0), m_nTileSizeTwips(0),
m_aVisibleArea({0, 0, 0, 0}), m_aVisibleArea({0, 0, 0, 0}),
m_bVisibleAreaSet(false), m_bVisibleAreaSet(false),
...@@ -850,7 +880,9 @@ static void reportError(LOKDocView* /*pDocView*/, const std::string& rString) ...@@ -850,7 +880,9 @@ static void reportError(LOKDocView* /*pDocView*/, const std::string& rString)
static void static void
setPart(LOKDocView* pDocView, const std::string& rString) setPart(LOKDocView* pDocView, const std::string& rString)
{ {
g_signal_emit(pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); LOKDocViewPrivate& priv = getPrivate(pDocView);
priv->m_nPartId = std::stoi(rString);
g_signal_emit(pDocView, doc_view_signals[PART_CHANGED], 0, priv->m_nPartId);
} }
static void static void
...@@ -1142,9 +1174,10 @@ callback (gpointer pData) ...@@ -1142,9 +1174,10 @@ callback (gpointer pData)
boost::property_tree::ptree aTree; boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree); boost::property_tree::read_json(aStream, aTree);
int nViewId = aTree.get<int>("viewId"); int nViewId = aTree.get<int>("viewId");
int nPart = aTree.get<int>("part");
const std::string& rRectangle = aTree.get<std::string>("selection"); const std::string& rRectangle = aTree.get<std::string>("selection");
if (rRectangle != "EMPTY") if (rRectangle != "EMPTY")
priv->m_aGraphicViewSelections[nViewId] = payloadToRectangle(pDocView, rRectangle.c_str()); priv->m_aGraphicViewSelections[nViewId] = ViewRectangle(nPart, payloadToRectangle(pDocView, rRectangle.c_str()));
else else
{ {
auto it = priv->m_aGraphicViewSelections.find(nViewId); auto it = priv->m_aGraphicViewSelections.find(nViewId);
...@@ -1229,8 +1262,9 @@ callback (gpointer pData) ...@@ -1229,8 +1262,9 @@ callback (gpointer pData)
boost::property_tree::ptree aTree; boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree); boost::property_tree::read_json(aStream, aTree);
int nViewId = aTree.get<int>("viewId"); int nViewId = aTree.get<int>("viewId");
int nPart = aTree.get<int>("part");
const std::string& rRectangle = aTree.get<std::string>("rectangle"); const std::string& rRectangle = aTree.get<std::string>("rectangle");
priv->m_aViewCursors[nViewId] = payloadToRectangle(pDocView, rRectangle.c_str()); priv->m_aViewCursors[nViewId] = ViewRectangle(nPart, payloadToRectangle(pDocView, rRectangle.c_str()));
gtk_widget_queue_draw(GTK_WIDGET(pDocView)); gtk_widget_queue_draw(GTK_WIDGET(pDocView));
break; break;
} }
...@@ -1240,8 +1274,9 @@ callback (gpointer pData) ...@@ -1240,8 +1274,9 @@ callback (gpointer pData)
boost::property_tree::ptree aTree; boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree); boost::property_tree::read_json(aStream, aTree);
int nViewId = aTree.get<int>("viewId"); int nViewId = aTree.get<int>("viewId");
int nPart = aTree.get<int>("part");
const std::string& rSelection = aTree.get<std::string>("selection"); const std::string& rSelection = aTree.get<std::string>("selection");
priv->m_aTextViewSelectionRectangles[nViewId] = payloadToRectangles(pDocView, rSelection.c_str()); priv->m_aTextViewSelectionRectangles[nViewId] = ViewRectangles(nPart, payloadToRectangles(pDocView, rSelection.c_str()));
gtk_widget_queue_draw(GTK_WIDGET(pDocView)); gtk_widget_queue_draw(GTK_WIDGET(pDocView));
break; break;
} }
...@@ -1263,9 +1298,10 @@ callback (gpointer pData) ...@@ -1263,9 +1298,10 @@ callback (gpointer pData)
boost::property_tree::ptree aTree; boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree); boost::property_tree::read_json(aStream, aTree);
int nViewId = aTree.get<int>("viewId"); int nViewId = aTree.get<int>("viewId");
int nPart = aTree.get<int>("part");
const std::string& rRectangle = aTree.get<std::string>("rectangle"); const std::string& rRectangle = aTree.get<std::string>("rectangle");
if (rRectangle != "EMPTY") if (rRectangle != "EMPTY")
priv->m_aCellViewCursors[nViewId] = payloadToRectangle(pDocView, rRectangle.c_str()); priv->m_aCellViewCursors[nViewId] = ViewRectangle(nPart, payloadToRectangle(pDocView, rRectangle.c_str()));
else else
{ {
auto it = priv->m_aCellViewCursors.find(nViewId); auto it = priv->m_aCellViewCursors.find(nViewId);
...@@ -1565,7 +1601,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) ...@@ -1565,7 +1601,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
if (itVisibility != priv->m_aViewCursorVisibilities.end() && !itVisibility->second) if (itVisibility != priv->m_aViewCursorVisibilities.end() && !itVisibility->second)
continue; continue;
GdkRectangle& rCursor = rPair.second; if (rPair.second.m_nPart != priv->m_nPartId)
continue;
GdkRectangle& rCursor = rPair.second.m_aRectangle;
if (rCursor.width < 30) if (rCursor.width < 30)
// Set a minimal width if it would be 0. // Set a minimal width if it would be 0.
rCursor.width = 30; rCursor.width = 30;
...@@ -1636,9 +1675,12 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) ...@@ -1636,9 +1675,12 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
} }
// Selections of other views. // Selections of other views.
for (std::pair<const int, std::vector<GdkRectangle>>& rPair : priv->m_aTextViewSelectionRectangles) for (auto& rPair : priv->m_aTextViewSelectionRectangles)
{ {
for (GdkRectangle& rRectangle : rPair.second) if (rPair.second.m_nPart != priv->m_nPartId)
continue;
for (GdkRectangle& rRectangle : rPair.second.m_aRectangles)
{ {
const GdkRGBA& rDark = getDarkColor(rPair.first); const GdkRGBA& rDark = getDarkColor(rPair.first);
// 75% transparency. // 75% transparency.
...@@ -1659,10 +1701,14 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) ...@@ -1659,10 +1701,14 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
} }
// Graphic selections of other views. // Graphic selections of other views.
for (std::pair<const int, GdkRectangle>& rPair : priv->m_aGraphicViewSelections) for (auto& rPair : priv->m_aGraphicViewSelections)
{ {
const ViewRectangle& rRectangle = rPair.second;
if (rRectangle.m_nPart != priv->m_nPartId)
continue;
const GdkRGBA& rDark = getDarkColor(rPair.first); const GdkRGBA& rDark = getDarkColor(rPair.first);
renderGraphicHandle(pDocView, pCairo, rPair.second, rDark); renderGraphicHandle(pDocView, pCairo, rRectangle.m_aRectangle, rDark);
} }
// Draw the cell cursor. // Draw the cell cursor.
...@@ -1674,10 +1720,6 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) ...@@ -1674,10 +1720,6 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
twipToPixel(priv->m_aCellCursor.y, priv->m_fZoom), twipToPixel(priv->m_aCellCursor.y, priv->m_fZoom),
twipToPixel(priv->m_aCellCursor.width, priv->m_fZoom), twipToPixel(priv->m_aCellCursor.width, priv->m_fZoom),
twipToPixel(priv->m_aCellCursor.height, priv->m_fZoom)); twipToPixel(priv->m_aCellCursor.height, priv->m_fZoom));
// priv->m_aCellCursor.x - 1,
// priv->m_aCellCursor.y - 1,
// priv->m_aCellCursor.width + 2,
// priv->m_aCellCursor.height + 2);
cairo_set_line_width(pCairo, 2.0); cairo_set_line_width(pCairo, 2.0);
cairo_stroke(pCairo); cairo_stroke(pCairo);
} }
...@@ -1685,15 +1727,17 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) ...@@ -1685,15 +1727,17 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
// Cell view cursors: they are colored. // Cell view cursors: they are colored.
for (auto& rPair : priv->m_aCellViewCursors) for (auto& rPair : priv->m_aCellViewCursors)
{ {
GdkRectangle& rCursor = rPair.second; const ViewRectangle& rCursor = rPair.second;
if (rCursor.m_nPart != priv->m_nPartId)
continue;
const GdkRGBA& rDark = getDarkColor(rPair.first); const GdkRGBA& rDark = getDarkColor(rPair.first);
cairo_set_source_rgb(pCairo, rDark.red, rDark.green, rDark.blue); cairo_set_source_rgb(pCairo, rDark.red, rDark.green, rDark.blue);
cairo_rectangle(pCairo, cairo_rectangle(pCairo,
twipToPixel(rCursor.x, priv->m_fZoom), twipToPixel(rCursor.m_aRectangle.x, priv->m_fZoom),
twipToPixel(rCursor.y, priv->m_fZoom), twipToPixel(rCursor.m_aRectangle.y, priv->m_fZoom),
twipToPixel(rCursor.width, priv->m_fZoom), twipToPixel(rCursor.m_aRectangle.width, priv->m_fZoom),
twipToPixel(rCursor.height, priv->m_fZoom)); twipToPixel(rCursor.m_aRectangle.height, priv->m_fZoom));
cairo_set_line_width(pCairo, 2.0); cairo_set_line_width(pCairo, 2.0);
cairo_stroke(pCairo); cairo_stroke(pCairo);
} }
...@@ -3119,6 +3163,7 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) ...@@ -3119,6 +3163,7 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart)
g_clear_error(&error); g_clear_error(&error);
} }
g_object_unref(task); g_object_unref(task);
priv->m_nPartId = nPart;
} }
SAL_DLLPUBLIC_EXPORT gchar* SAL_DLLPUBLIC_EXPORT gchar*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment