Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit ebef56d

Browse files
authored
Add read only mode for expanded doc, fix undo listener for expanded doc (#79)
* Add read only mode for expanded doc, fix undo listener for expanded doc * Fix cursor movement in read only mode
1 parent 338449e commit ebef56d

File tree

12 files changed

+102
-150
lines changed

12 files changed

+102
-150
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.0.2
1+
v0.0.3

libreoffice-core/desktop/inc/lib/wasm_extensions.hxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ struct DESKTOP_DLLPUBLIC WasmDocumentExtension : public _LibreOfficeKitDocument
103103
std::string getPageColor();
104104
std::string getPageOrientation();
105105

106-
_LibreOfficeKitDocument* loadFromExpanded(LibreOfficeKit* pThis, desktop::ExpandedDocument expandedDoc, const char* pFilterOptions = nullptr, const int documentId = 0);
106+
_LibreOfficeKitDocument* loadFromExpanded(LibreOfficeKit* pThis, desktop::ExpandedDocument expandedDoc, const int documentId = 0, const bool readOnly = false);
107107

108108
std::optional<std::pair<std::string, std::vector<sal_Int8>>> getExpandedPart(const std::string& path) const;
109109
void removePart(const std::string& path) const;
@@ -113,7 +113,7 @@ struct DESKTOP_DLLPUBLIC WasmDocumentExtension : public _LibreOfficeKitDocument
113113

114114
struct DESKTOP_DLLPUBLIC WasmOfficeExtension : public _LibreOfficeKit
115115
{
116-
_LibreOfficeKitDocument* documentExpandedLoad(desktop::ExpandedDocument expandedDoc, std::string name, const char* pFilterOptions, const int documentId = 0);
116+
_LibreOfficeKitDocument* documentExpandedLoad(desktop::ExpandedDocument expandedDoc, std::string name, const int documentId = 0, const bool readOnly = false);
117117
};
118118

119119
}

libreoffice-core/desktop/source/app/main_wasm.cxx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <optional>
12
#define LOK_USE_UNSTABLE_API
23
#include <unordered_set>
34
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -341,13 +342,33 @@ class DocumentClient final : public INotifier
341342
SAL_WARN("wasm", "Failed to setup undo listener");
342343
}
343344
}
344-
explicit DocumentClient(desktop::ExpandedDocument expandedDoc, std::string name)
345+
346+
DocumentClient(desktop::ExpandedDocument expandedDoc, std::string name, std::optional<bool> readOnly)
345347
: ref_(++document_id_counter)
346348
{
347-
desktop::WasmOfficeExtension* ext = static_cast<desktop::WasmOfficeExtension*>(instance()->get());
348-
auto doc = ext->documentExpandedLoad(expandedDoc, name, nullptr, ref_);
349+
desktop::WasmOfficeExtension* officeExt = static_cast<desktop::WasmOfficeExtension*>(instance()->get());
350+
auto doc = officeExt->documentExpandedLoad(expandedDoc, name, ref_, readOnly.value_or(false));
349351
lok::Document* aDoc = new lok::Document(doc);
350352
doc_ = aDoc;
353+
354+
using namespace css;
355+
using namespace css::uno;
356+
try
357+
{
358+
Reference<document::XUndoManagerSupplier> xUndoSupplier(ext()->mxComponent, UNO_QUERY);
359+
if (!xUndoSupplier.is())
360+
return;
361+
Reference<document::XUndoManager> xUndoManager(xUndoSupplier->getUndoManager());
362+
363+
if (!xUndoManager.is())
364+
return;
365+
366+
undoListener_.set(new UndoManagerContextListener(xUndoManager, writer(), this));
367+
}
368+
catch (const Exception&)
369+
{
370+
SAL_WARN("wasm", "Failed to setup undo listener");
371+
}
351372
}
352373
~DocumentClient()
353374
{
@@ -934,7 +955,7 @@ EMSCRIPTEN_BINDINGS(lok)
934955

935956
class_<DocumentClient>("Document")
936957
.constructor<std::string>()
937-
.constructor<desktop::ExpandedDocument, std::string>()
958+
.constructor<desktop::ExpandedDocument, std::string, std::optional<bool>>()
938959
.function("valid", &DocumentClient::valid)
939960
.function("saveAs", &DocumentClient::saveAs)
940961
.function("getParts", &DocumentClient::getParts)

libreoffice-core/desktop/source/lib/wasm_extensions.cxx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ std::string WasmDocumentExtension::getPageOrientation ()
221221
return bIsLandscape ? "landscape" : "portrait";
222222
}
223223

224-
_LibreOfficeKitDocument* WasmOfficeExtension::documentExpandedLoad(desktop::ExpandedDocument expandedDoc, std::string name, const char* pFilterOptions, const int documentId)
224+
_LibreOfficeKitDocument* WasmOfficeExtension::documentExpandedLoad(desktop::ExpandedDocument expandedDoc, std::string name, const int documentId, const bool readOnly)
225225
{
226226
LibreOfficeKitDocument* pDoc = NULL;
227227
desktop::WasmDocumentExtension* ext
@@ -230,7 +230,7 @@ _LibreOfficeKitDocument* WasmOfficeExtension::documentExpandedLoad(desktop::Expa
230230
LibreOfficeKit* pThis = static_cast<LibreOfficeKit*>(this);
231231

232232

233-
return ext->loadFromExpanded(pThis, expandedDoc, pFilterOptions, documentId);
233+
return ext->loadFromExpanded(pThis, expandedDoc, documentId, readOnly);
234234
}
235235

236236

@@ -239,7 +239,7 @@ void ExpandedDocument::addPart(std::string path, std::string content)
239239
parts.emplace_back(std::move(path), std::move(content));
240240
}
241241

242-
_LibreOfficeKitDocument* WasmDocumentExtension::loadFromExpanded(LibreOfficeKit* pThis, desktop::ExpandedDocument expandedDoc, const char* pFilterOptions, const int documentId)
242+
_LibreOfficeKitDocument* WasmDocumentExtension::loadFromExpanded(LibreOfficeKit* pThis, desktop::ExpandedDocument expandedDoc, const int documentId, const bool readOnly)
243243
{
244244
using namespace com::sun::star;
245245
uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
@@ -296,15 +296,22 @@ _LibreOfficeKitDocument* WasmDocumentExtension::loadFromExpanded(LibreOfficeKit*
296296
utl::MediaDescriptor aMediaDescriptor;
297297

298298
// Expanded Storage only supports .DOCX
299-
aMediaDescriptor["FilterName"] <<= OUString("MS Word 2007 XML"); // just hardcode this for now
300-
aMediaDescriptor["MacroExecutionMode"] <<= document::MacroExecMode::NEVER_EXECUTE;
299+
aMediaDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= OUString("MS Word 2007 XML"); // just hardcode this for now
300+
aMediaDescriptor[utl::MediaDescriptor::PROP_MACROEXECUTIONMODE] <<= document::MacroExecMode::NEVER_EXECUTE;
301301
// We don't have a general document input stream,
302302
// so we pass in an empty one. Down the line its crucial we
303303
// check if we are currently loading from expanded storage
304304
// and use the storage instead of the stream
305-
aMediaDescriptor["InputStream"] <<= xEmptyInputStream;
305+
aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM] <<= xEmptyInputStream;
306306
// Silences various exceptions
307-
aMediaDescriptor["Silent"] <<= true;
307+
aMediaDescriptor[utl::MediaDescriptor::PROP_SILENT] <<= true;
308+
309+
if (readOnly)
310+
{
311+
aMediaDescriptor[utl::MediaDescriptor::PROP_READONLY] <<= true;
312+
// disable comments which are still enabled with read only:
313+
aMediaDescriptor[utl::MediaDescriptor::PROP_VIEWONLY] <<= true;
314+
}
308315

309316
{
310317
SolarMutexGuard aGuard;

libreoffice-core/desktop/wasm/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,14 @@ export async function loadDocumentFromExpandedParts<
393393
T extends DocumentClient = DocumentClient,
394394
>(
395395
name: string,
396-
parts: Array<{path: string, content: ArrayBuffer}>
396+
parts: Array<{path: string, content: ArrayBuffer}>,
397+
readOnly = false
397398
): Promise<DocumentClient | null> {
398399
const [i, future] = registerFuture<DocumentRef | null>();
399400
const message: ToWorker = {
400401
f: 'loadFromExpandedParts',
401402
i,
402-
a: [name, parts],
403+
a: [name, parts, readOnly],
403404
};
404405
loadWorkerOnce().postMessage(message);
405406
return future.promise.then(documentClient<T>);

libreoffice-core/desktop/wasm/shared.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ export type GlobalMessage = {
2020
/** load the document with the file name `name` and content `blob`
2121
@returns the corresponding document on success, null otherwise */
2222
load(name: string, blob: Blob): DocumentRef | null;
23-
loadFromExpandedParts(name: string, data: Array<ExpandedPart>): DocumentRef | null;
24-
// NOTE: Disabled until unoembind startup cost is under 1s
25-
// importScript(url: string): void;
23+
loadFromExpandedParts(name: string, data: Array<ExpandedPart>, readOnly: boolean): DocumentRef | null;
2624
preload(): void;
2725
setIsMacOSForConfig(): void;
2826
};

libreoffice-core/desktop/wasm/soffice.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ export declare class ExpandedDocument {
156156

157157
export type ExpandedPart = { path: string; content: ArrayBuffer };
158158

159-
/** Embind ocument class, see main_wasm.cxx */
159+
/** Embind document class, see main_wasm.cxx */
160160
export declare class Document {
161161
constructor(path: string): void;
162-
constructor(expanded: ExpandedDocument, name: string): void;
162+
constructor(expanded: ExpandedDocument, name: string, readOnly: boolean): void;
163163
delete(): void;
164164

165165
valid(): boolean;

libreoffice-core/desktop/wasm/worker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ const globalHandler: GlobalMethod = {
8888
docMap[ref] = doc;
8989
return ref;
9090
},
91-
loadFromExpandedParts: function(name: string, data: Array<ExpandedPart>) {
91+
loadFromExpandedParts: function(name: string, data: Array<ExpandedPart>, readOnly: boolean) {
9292
const { Document, ExpandedDocument} = lok;
9393
const expandedDoc = new ExpandedDocument();
9494
for (const part of data) {
9595
expandedDoc.addPart(part.path, part.content);
9696
}
9797

98-
const doc = new Document(expandedDoc, name);
98+
const doc = new Document(expandedDoc, name, readOnly);
9999
const ref = doc.ref();
100100

101101
if (!doc.valid()) {

libreoffice-core/sw/source/uibase/docvw/edtwin.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1491,8 +1491,10 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
14911491

14921492
KeyEvent aKeyEvent( rKEvt );
14931493
// look for vertical mappings
1494-
if( !bIsViewReadOnly && !rSh.IsSelFrameMode() && !rSh.IsObjSelected() )
1494+
// MACRO-2720: Allow basic cursor movement in read only mode {
1495+
if( !rSh.IsSelFrameMode() && !rSh.IsObjSelected() )
14951496
{
1497+
// MACRO-2720: }
14961498
if( KEY_UP == nKey || KEY_DOWN == nKey ||
14971499
KEY_LEFT == nKey || KEY_RIGHT == nKey )
14981500
{

libreoffice-core/sw/source/uibase/wrtsh/move.cxx

Lines changed: 18 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -111,99 +111,51 @@ bool SwWrtShell::SimpleMove( FNSimpleMove FnSimpleMove, bool bSelect )
111111
bool SwWrtShell::Left( SwCursorSkipMode nMode, bool bSelect,
112112
sal_uInt16 nCount, bool bBasicCall, bool bVisual )
113113
{
114-
if ( !bSelect && !bBasicCall && IsCursorReadonly() && !GetViewOptions()->IsSelectionInReadonly())
115-
{
116-
Point aTmp( VisArea().Pos() );
117-
aTmp.AdjustX( -(VisArea().Width() * nReadOnlyScrollOfst / 100) );
118-
m_rView.SetVisArea( aTmp );
119-
return true;
120-
}
121-
else
122-
{
123-
ShellMoveCursor aTmp( this, bSelect );
124-
return SwCursorShell::Left( nCount, nMode, bVisual );
125-
}
114+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???) {
115+
ShellMoveCursor aTmp( this, bSelect );
116+
return SwCursorShell::Left( nCount, nMode, bVisual );
117+
// MACRO-2720: }
126118
}
127119

128120
bool SwWrtShell::Right( SwCursorSkipMode nMode, bool bSelect,
129121
sal_uInt16 nCount, bool bBasicCall, bool bVisual )
130122
{
131-
if ( !bSelect && !bBasicCall && IsCursorReadonly() && !GetViewOptions()->IsSelectionInReadonly() )
132-
{
133-
Point aTmp( VisArea().Pos() );
134-
aTmp.AdjustX(VisArea().Width() * nReadOnlyScrollOfst / 100 );
135-
aTmp.setX( m_rView.SetHScrollMax( aTmp.X() ) );
136-
m_rView.SetVisArea( aTmp );
137-
return true;
138-
}
139-
else
140-
{
141-
ShellMoveCursor aTmp( this, bSelect );
142-
return SwCursorShell::Right( nCount, nMode, bVisual );
143-
}
123+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???) {
124+
ShellMoveCursor aTmp( this, bSelect );
125+
return SwCursorShell::Right( nCount, nMode, bVisual );
126+
// MACRO-2720: }
144127
}
145128

146129
bool SwWrtShell::Up( bool bSelect, sal_uInt16 nCount, bool bBasicCall )
147130
{
148-
if ( !bSelect && !bBasicCall && IsCursorReadonly() && !GetViewOptions()->IsSelectionInReadonly())
149-
{
150-
Point aTmp( VisArea().Pos() );
151-
aTmp.AdjustY( -(VisArea().Height() * nReadOnlyScrollOfst / 100) );
152-
m_rView.SetVisArea( aTmp );
153-
return true;
154-
}
131+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???)
155132

156133
ShellMoveCursor aTmp( this, bSelect );
157134
return SwCursorShell::Up(nCount);
158135
}
159136

160137
bool SwWrtShell::Down( bool bSelect, sal_uInt16 nCount, bool bBasicCall )
161138
{
162-
if ( !bSelect && !bBasicCall && IsCursorReadonly() && !GetViewOptions()->IsSelectionInReadonly())
163-
{
164-
Point aTmp( VisArea().Pos() );
165-
aTmp.AdjustY(VisArea().Height() * nReadOnlyScrollOfst / 100 );
166-
aTmp.setY( m_rView.SetVScrollMax( aTmp.Y() ) );
167-
m_rView.SetVisArea( aTmp );
168-
return true;
169-
}
139+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???)
170140

171141
ShellMoveCursor aTmp( this, bSelect );
172142
return SwCursorShell::Down(nCount);
173143
}
174144

175145
bool SwWrtShell::LeftMargin( bool bSelect, bool bBasicCall )
176146
{
177-
if ( !bSelect && !bBasicCall && IsCursorReadonly() )
178-
{
179-
Point aTmp( VisArea().Pos() );
180-
aTmp.setX( DOCUMENTBORDER );
181-
m_rView.SetVisArea( aTmp );
182-
return true;
183-
}
184-
else
185-
{
186-
ShellMoveCursor aTmp( this, bSelect );
187-
return SwCursorShell::LeftMargin();
188-
}
147+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???) {
148+
ShellMoveCursor aTmp( this, bSelect );
149+
return SwCursorShell::LeftMargin();
150+
// MACRO-2720: }
189151
}
190152

191153
bool SwWrtShell::RightMargin( bool bSelect, bool bBasicCall )
192154
{
193-
if ( !bSelect && !bBasicCall && IsCursorReadonly() )
194-
{
195-
Point aTmp( VisArea().Pos() );
196-
aTmp.setX( GetDocSize().Width() - VisArea().Width() + DOCUMENTBORDER );
197-
if( DOCUMENTBORDER > aTmp.X() )
198-
aTmp.setX( DOCUMENTBORDER );
199-
m_rView.SetVisArea( aTmp );
200-
return true;
201-
}
202-
else
203-
{
204-
ShellMoveCursor aTmp( this, bSelect );
205-
return SwCursorShell::RightMargin(bBasicCall);
206-
}
155+
// MACRO-2720: Allow basic cursor movement in read only mode (why is this even necessary???) {
156+
ShellMoveCursor aTmp( this, bSelect );
157+
return SwCursorShell::RightMargin(bBasicCall);
158+
// MACRO-2720: }
207159
}
208160

209161
bool SwWrtShell::GoStart( bool bKeepArea, bool *pMoveTable,

0 commit comments

Comments
 (0)