ultimatepp/bazaar/OfficeAutomation/OfficeAutomation.cpp
koldo 623f2ef65d *OfficeAutomation: Removed MessageBox() calls thanks to ratah
git-svn-id: svn://ultimatepp.org/upp/trunk@4286 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2011-12-09 13:22:26 +00:00

2492 lines
62 KiB
C++

#include <Core/Core.h>
using namespace Upp;
#ifndef PLATFORM_WIN32
#error Sorry: This platform is not supported!. Look for OfficeAutomation in Bazaar Upp Forum to search for info and new news
#endif
#include <winnls.h>
#include <Functions4U/Functions4U.h>
#include "OfficeAutomation.h"
#include "OfficeAutomationBase.h"
////////////////////////////////////////////////////////////////////////////////////////
VariantOle::VariantOle() {
VariantInit(&var);
VariantClear(&var);
}
VariantOle::~VariantOle() {
if (var.vt == VT_BSTR)
SysFreeString(var.bstrVal);
}
void VariantOle::Bool(bool val) {
var.vt = VT_BOOL;
var.boolVal = val;
}
void VariantOle::Int(int val) {
var.vt = VT_I4;
var.intVal = val;
}
void VariantOle::Int4(long val) {
var.vt = VT_I4;
var.lVal = val;
}
void VariantOle::Real4(float val) {
var.vt = VT_R4;
var.fltVal = val;
}
void VariantOle::Real8(double val) {
var.vt = VT_R8;
var.dblVal = val;
}
void VariantOle::BString(String str) {
WCHAR wfileName[1024*sizeof(WCHAR)];
MultiByteToWideChar(CP_UTF8, 0, str, -1, wfileName, sizeof(wfileName)/sizeof(wfileName[0]));
var.vt = VT_BSTR;
var.bstrVal = ::SysAllocString(wfileName);
}
void VariantOle::Optional() {
var.vt = VT_ERROR;
var.scode = DISP_E_PARAMNOTFOUND;
}
void VariantOle::ObjectOle(::ObjectOle val) {
var.vt = VT_DISPATCH;
var.pdispVal = val;
}
void VariantOle::Time(Upp::Time t) {
var.vt = VT_DATE;
SYSTEMTIME stime;
stime.wDay = t.day;
stime.wMonth = t.month;
stime.wYear = t.year;
stime.wHour = t.hour;
stime.wMinute = t.minute;
stime.wSecond = t.second;
SystemTimeToVariantTime(&stime, &(var.date));
}
void VariantOle::ArrayDim(int sizeX) {
var.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[1]; // 1 dimension
sab[0].lLbound = 1; sab[0].cElements = sizeX;
var.parray = SafeArrayCreate(VT_VARIANT, 1, sab);
}
void VariantOle::ArrayDim(int sizeX, int sizeY) {
var.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND sab[2]; // 2 dimension
sab[0].lLbound = 1; sab[0].cElements = sizeY;
sab[1].lLbound = 1; sab[1].cElements = sizeX;
var.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
}
void VariantOle::ArraySetValue(int x, ::Value value) {
VariantOle tmp;
tmp.Value(value);
long indices[] = {x};
SafeArrayPutElement(var.parray, indices, (void *)&tmp);
}
void VariantOle::ArraySetVariant(int x, VariantOle &value) {
long indices[] = {x};
SafeArrayPutElement(var.parray, indices, (void *)&value);
}
void VariantOle::ArraySetValue(int x, int y, ::Value value) {
VariantOle tmp;
tmp.Value(value);
long indices[] = {y, x};
SafeArrayPutElement(var.parray, indices, (void *)&tmp);
}
void VariantOle::ArraySetVariant(int x, int y, VariantOle &value) {
long indices[] = {y, x};
SafeArrayPutElement(var.parray, indices, (void *)&value);
}
void VariantOle::Value(::Value value) {
if(value.Is<bool>()) {
bool v = value;
Bool(v);
} else if(value.Is<int>()) {
int v = value;
Int(v);
} else if(value.Is<int64>()) {
int64 v = value;
Int4((long)v);
//} else if(value.Is<float>()) {
// float v = value;
// Real4(v);
} else if(value.Is<double>()) {
double v = value;
Real8(v);
} else if(value.Is<String>()) {
String v = value;
BString(v);
} else if(IsDateTime(value)) {
Upp::Time v = value;
Time(v);
} else {
String v = value;
BString(v);
}
}
////////////////////////////////////////////////////////////////////////////////////////
int Ole::numOleInit = 0;
void Ole::Init() { // Initialize COM for this thread
if (numOleInit == 0) {
OleInitialize(NULL);
CoInitialize(NULL);
numOleInit++;
}
}
bool Ole::Close() { // Uninitialize COM for this thread
numOleInit--;
if (numOleInit == 0)
CoUninitialize();
if (numOleInit < 0) { // This is a mistake
numOleInit = 0;
return false;
} else
return true;
}
// Invoke() - Automation helper function
bool Ole::Invoke(int autoType, VARIANT *pvResult, IDispatch *pDisp, String name, int cArgs ...) {
// Begin variable-argument lis
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
LOG("OfficeAutomation internal error. ObjectOle included is null");
return false;
}
// Variables used
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
WString wname = name.ToWString();
WStringBuffer ptName(wname);
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed
hr = pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR *)&ptName, 1, LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
sprintf(buf, "OfficeAutomation internal error. Command \"%s\" not found for object or problem when running it", szName);
LOG(buf);
return false;
}
VARIANT *pArgs = new VARIANT[cArgs+1]; // Allocate memory for arguments
for(int i = 0; i < cArgs; i++) // Extract arguments
pArgs[i] = va_arg(marker, VARIANT);
dp.cArgs = cArgs; // Build DISPPARAMS
dp.rgvarg = pArgs;
if(autoType & DISPATCH_PROPERTYPUT) { // Handle special-case for property-puts!
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
va_end(marker); // End variable-argument section
delete [] pArgs;
if(FAILED(hr)) {
sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr);
LOG(buf);
return false;
}
return true;
}
ObjectOle Ole::CreateObject(String application) {
CLSID clsid;
HRESULT hr = CLSIDFromProgID(application.ToWString(), &clsid); // Get CLSID for our server
if(FAILED(hr)) {
LOG("CLSIDFromProgID() failed");
return NULL;
}
ObjectOle app;
// Start server and get IDispatch
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&app);
if(FAILED(hr)) {
LOG("OfficeAutomation internal error. Application not registered properly");
return NULL;
}
return app;
}
ObjectOle Ole::GetObject(ObjectOle from, String which) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_PROPERTYGET, &result, from, which, 0))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::GetObject(ObjectOle from, String which, VariantOle &value) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_PROPERTYGET, &result, from, which, 1, value.var))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::GetObject(ObjectOle from, String which, VariantOle &value, VariantOle &value2) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_PROPERTYGET, &result, from, which, 2, value.var, value2.var))
return NULL;
else
return result.pdispVal;
}
Value Ole::GetValue(ObjectOle from, String which) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_PROPERTYGET|DISPATCH_METHOD, &result, from, which, 0))
return "";
return GetVARIANT(result);
}
bool Ole::SetValue(ObjectOle from, String which, VariantOle &value) {
return Ole::Invoke(DISPATCH_PROPERTYPUT, NULL, from, which, 1, value.var);
}
bool Ole::SetValue(ObjectOle from, String which, VariantOle &value, VariantOle &value2) {
return Ole::Invoke(DISPATCH_PROPERTYPUT, NULL, from, which, 2, value.var, value2.var);
}
bool Ole::SetValue(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3) {
return Ole::Invoke(DISPATCH_PROPERTYPUT, NULL, from, which, 3, value.var, value2.var, value3.var);
}
// result var is not used but OpenOffice automation requires it (I do not why)
bool Ole::Method(ObjectOle from, String which) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 0);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 1, value.var);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value, VariantOle &value2) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 2, value.var, value2.var);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 3, value.var, value2.var, value3.var);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3, VariantOle &value4) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 3, value.var, value2.var, value3.var, value4.var);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3, VariantOle &value4, VariantOle &value5) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 3, value.var, value2.var, value3.var, value4.var, value5.var);
}
bool Ole::Method(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3, VariantOle &value4, VariantOle &value5, VariantOle &value6, VariantOle &value7, VariantOle &value8, VariantOle &value9, VariantOle &value10, VariantOle &value11) {
VARIANT result;
VariantInit(&result);
return Ole::Invoke(DISPATCH_METHOD, &result, from, which, 11, value.var, value2.var, value3.var, value4.var, value5.var, value6.var, value7.var, value8.var, value9.var, value10.var, value11.var);
}
ObjectOle Ole::MethodGet(ObjectOle from, String which) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 0))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::MethodGet(ObjectOle from, String which, VariantOle &value) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 1, value.var))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::MethodGet(ObjectOle from, String which, VariantOle &value, VariantOle &value2) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 2, value.var, value2.var))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::MethodGet(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 3, value.var, value2.var, value3.var))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::MethodGet(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3, VariantOle &value4) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 4, value.var, value2.var, value3.var, value4.var))
return NULL;
else
return result.pdispVal;
}
ObjectOle Ole::MethodGet(ObjectOle from, String which, VariantOle &value, VariantOle &value2, VariantOle &value3, VariantOle &value4, VariantOle &value5) {
VARIANT result;
VariantInit(&result);
if(!Ole::Invoke(DISPATCH_METHOD, &result, from, which, 4, value.var, value2.var, value3.var, value4.var, value5.var))
return NULL;
else
return result.pdispVal;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INITBLOCK {
PluginRegister(OfficeSheet, MSSheet, "Microsoft");
}
MSSheet::MSSheet() {
App = Books = Book = Sheet = Range = NULL;
quit = false;
App = Ole::CreateObject("Excel.Application");
if (!(Books = Ole::GetObject(App, "Workbooks"))) {
LOG("Excel workbooks not loaded properly");
return;
}
}
MSSheet::~MSSheet() {
if (Range) {
Range->Release();
Range = 0;
}
if (Sheet) {
Sheet->Release();
Sheet = 0;
}
if (Book) {
Book->Release();
Book = 0;
}
if (Books) {
Books->Release();
Books = 0;
}
if (App) {
Quit();
App->Release();
App = 0;
}
}
bool MSSheet::IsAvailable() {
ObjectOle app = Ole::CreateObject("Excel.Application");
if (!app)
return false;
else {
app->Release();
return true;
}
}
bool MSSheet::SetVisible(bool visible) {
if (!Books)
return false;
VariantOle vVisible;
vVisible.Int4(visible? 1: 0);
return Ole::SetValue(App, "Visible", vVisible);
}
bool MSSheet::SetSaved(bool saved) {
if (!Books && !Book)
return false;
// Set .Saved property of workbook to TRUE so we aren't prompted
// to save when we tell Excel to quit...
VariantOle vSaved;
vSaved.Int4(saved? 1: 0);
return Ole::SetValue(Book, "Saved", vSaved);
}
bool MSSheet::Quit()
{
if (!quit) {
quit = true;
return Ole::Method(App, "Quit");
}
return true;
}
bool MSSheet::AddSheet(bool visible) {
if (!Books)
return false;
if (!(Book = Ole::GetObject(Books, "Add")))
return false;
if (!(Sheet = Ole::GetObject(App, "ActiveSheet")))
return false;
SetVisible(visible);
return true;
}
bool MSSheet::OpenSheet(String fileName, bool visible) {
if (!Books)
return false;
VariantOle vFileName;
vFileName.BString(fileName);
if (!(Book = Ole::GetObject(Books, "Open", vFileName)))
return false;
if (!(Sheet = Ole::GetObject(App, "ActiveSheet")))
return false;
SetVisible(visible);
return true;
}
bool MSSheet::Select(String range) {
VariantOle vRange;
vRange.BString(range);
if (!(Range = Ole::GetObject(Sheet, "Range", vRange)))
return false;
return true;
}
bool MSSheet::Select(int fromX, int fromY, int toX, int toY) {
String range = OfficeSheet::ColRowToCell(fromX, fromY) + ":" + OfficeSheet::ColRowToCell(toX, toY);
VariantOle vRange;
vRange.BString(range);
if (!(Range = Ole::GetObject(Sheet, "Range", vRange)))
return false;
return true;
}
bool MSSheet::Select() {
if (!(Range = Ole::GetObject(Sheet, "Cells"))) // ActiveSheet.Cells.Select
return false;
return Ole::Method(Range, "Select");
}
void MSSheet::DefMatrix(int width, int height) {
Matrix.ArrayDim(width, height);
}
void MSSheet::SetMatrixValue(int x, int y, ::Value value) {
Matrix.ArraySetValue(x, y, value);
}
bool MSSheet::FillSelectionMatrix() {
if (!Range)
return false;
bool ret = Ole::Invoke(DISPATCH_PROPERTYPUT, NULL, Range, "Value", 1, Matrix.var);
return ret;
}
// cell in textual format like "B14"
bool MSSheet::SetValue(String cell, Value value) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return MSSheet::SetValue(col, row, value);
}
bool MSSheet::SetValue(int col, int row, Value value) {
if (!Sheet)
return false;
VariantOle x, y, val;
x.Int4(col);
y.Int4(row);
val.Value(value);
return Ole::SetValue(Sheet, "Cells", val, x, y);
}
bool MSSheet::SetValue(Value value) {
if (!Sheet)
return false;
if (!Range)
return false;
VariantOle val;
val.Value(value);
return Ole::SetValue(Range, "Value", val);
}
bool MSSheet::Replace(Value search, Value replace) {
if (!App)
return false;
ObjectOle selection; // Call Application.Selection.Replace(search, replace)
if (!(selection = Ole::GetObject(App, "Selection")))
return false;
VariantOle vSearch, vReplace;
vSearch.Value(search);
vReplace.Value(replace);
bool ret = Ole::Method(selection, "Replace", vReplace, vSearch);
selection->Release();
return ret;
}
Value MSSheet::GetValue(int col, int row) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
return Ole::GetValue(Ole::GetObject(Sheet, "Cells", x, y), "value");
}
Value MSSheet::GetText(int col, int row) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
return Ole::GetValue(Ole::GetObject(Sheet, "Cells", x, y), "text");
}
Value MSSheet::GetValue(String cell) {
int row, col;
OfficeSheet::CellToColRow(cell, col, row);
return GetValue(col, row);
}
Value MSSheet::GetText(String cell) {
int row, col;
OfficeSheet::CellToColRow(cell, col, row);
return GetText(col, row);
}
// cell in textual format like "B14"
bool MSSheet::SetHyperlink(String cell, String address, String value) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetHyperlink(col, row, address, value);
}
bool MSSheet::SetHyperlink(int col, int row, String address, String value) {
if (!Sheet)
return false;
if (!Select(col, row, col, row))
return false;
return SetHyperlink(address, value);
}
bool MSSheet::SetHyperlink(String address, String value) {
if (!Sheet)
return false;
if (!Range)
return false;
ObjectOle hyperlinks = Ole::GetObject(Sheet, "Hyperlinks");
VariantOle textToDisplay, screenTip, subAddress, saddress, range;
textToDisplay.BString(value);
screenTip.BString("");
subAddress.BString("");
saddress.BString(address);
range.ObjectOle(Range);
bool ret = Ole::MethodGet(hyperlinks, "Add", textToDisplay, screenTip, subAddress, saddress, range);
hyperlinks->Release();
return ret;
}
bool MSSheet::SaveAs(String fileName, String type) {
if (!Book)
return false;
if (type[0] == '.')
type = type.Mid(1);
fileName = ForceExt(fileName, "." + type);
VariantOle vFileName, vType;
vFileName.BString(fileName);
if (type == "csv")
vType.Int(6);
else if (type == "html")
vType.Int(44);
else if (type == "txt")
vType.Int(20);
else if (type == "xlsx")
vType.Int(51);
else // xls
vType.Int(-4143);
bool opened = false;
if (FileExists(fileName)) {
if (!FileToTrashBin(fileName))
opened = true;
}
int ret;
if (opened)
ret = Ole::Method(Book, "Save");
else
ret = Ole::Method(Book, "SaveAs", vType, vFileName);
return (bool)ret;
}
bool MSSheet::SetBold(String cell, bool bold) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetBold(col, row, bold);
}
bool MSSheet::SetBold(int col, int row, bool bold) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
VariantOle val;
val.Bool(bold);
return Ole::SetValue(Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Font"), "Bold", val);
}
bool MSSheet::SetBold(bool bold) {
if (!Range)
return false;
VariantOle val;
val.Bool(bold);
return Ole::SetValue(Ole::GetObject(Range, "Font"), "Bold", val);
}
bool MSSheet::SetItalic(String cell, bool italic) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetItalic(col, row, italic);
}
bool MSSheet::SetItalic(int col, int row, bool italic) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
VariantOle val;
val.Bool(italic);
return Ole::SetValue(Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Font"), "Italic", val);
}
bool MSSheet::SetItalic(bool italic) {
if (!Range)
return false;
VariantOle val;
val.Bool(italic);
return Ole::SetValue(Ole::GetObject(Range, "Font"), "Italic", val);
}
bool MSSheet::SetUnderline(String cell, bool underline) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetUnderline(col, row, underline);
}
bool MSSheet::SetUnderline(int col, int row, bool underline) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
VariantOle val;
val.Bool(underline);
return Ole::SetValue(Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Font"), "Underline", val);
}
bool MSSheet::SetUnderline(bool underline) {
if (!Range)
return false;
VariantOle val;
val.Bool(underline);
return Ole::SetValue(Ole::GetObject(Range, "Font"), "Underline", val);
}
bool MSSheet::SetHorizAlignment(String cell, int alignment) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetHorizAlignment(col, row, alignment);
}
bool MSSheet::SetHorizAlignment(int col, int row, int alignment) {
if (!Sheet)
return false;
if (alignment < 1 || alignment >= OfficeSheet::MAX_JUSTIFY)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
int justifyConst[] = {-4131, -4108, -4152, -4130, -4160, -4107};
VariantOle cvalue;
cvalue.Int(justifyConst[alignment]);
return Ole::SetValue(Ole::GetObject(Sheet, "Cells", x, y), "HorizontalAlignment", cvalue);
}
bool MSSheet::SetVertAlignment(String cell, int alignment) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetVertAlignment(col, row, alignment);
}
bool MSSheet::SetVertAlignment(int col, int row, int alignment) {
if (!Sheet)
return false;
if (alignment < 1 || alignment >= OfficeSheet::MAX_JUSTIFY)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
int justifyConst[] = {-4131, -4108, -4152, -4130, -4160, -4107};
VariantOle cvalue;
cvalue.Int(justifyConst[alignment]);
return Ole::SetValue(Ole::GetObject(Sheet, "Cells", x, y), "VerticalAlignment", cvalue);
}
bool MSSheet::SetBorder(int borderIndx, int lineStyle, int weight, Color color) {
if (!Range)
return false;
ObjectOle borders = Ole::GetObject(Range, "Borders");
if (!borders)
return false;
bool ret = SetBorder(borders, borderIndx, lineStyle, weight, color);
borders->Release();
return ret;
}
bool MSSheet::SetBorder(int col, int row, int borderIndx, int lineStyle, int weight, Color color) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
ObjectOle borders = Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Borders");
if (!borders)
return false;
bool ret = SetBorder(borders, borderIndx, lineStyle, weight, color);
borders->Release();
return ret;
}
bool MSSheet::SetBorder(ObjectOle &borders, int borderIndx, int lineStyle, int weight, Color color) {
int borderIndxConst[] = {5, 6, 7, 8, 9, 10};
VariantOle item;
item.Int4(borderIndxConst[borderIndx]);
ObjectOle border = Ole::GetObject(borders, "Item", item);
if (!border)
return false;
int lineStyles[] = {-4142, 1, -4115, 4, -4118};
VariantOle val;
val.Int4(lineStyles[lineStyle]);
if(!Ole::SetValue(border, "LineStyle", val))
return false;
int weights[] = {1, -4138, 2, 4};
val.Int4(weights[weight]);
if(!Ole::SetValue(border, "Weight", val))
return false;
VariantOle cvalue;
cvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(border, "Color", cvalue);
}
bool MSSheet::SetFont(String cell, String name, int size)
{
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetFont(col, row, name, size);
}
bool MSSheet::SetFont(int col, int row, String name, int size) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
ObjectOle font = Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Font");
if (!font)
return false;
VariantOle vName;
vName.BString(name);
if(!Ole::SetValue(font, "Name", vName))
return false;
VariantOle vSize;
vSize.Int(size);
bool ret = Ole::SetValue(font, "Size", vSize);
font->Release();
return ret;
}
bool MSSheet::SetFont(String name, int size) {
if (!Range)
return false;
ObjectOle font = Ole::GetObject(Range, "Font");
if (!font)
return false;
VariantOle vName;
vName.BString(name);
if(!Ole::SetValue(font, "Name", vName))
return false;
VariantOle vSize;
vSize.Int(size);
bool ret = Ole::SetValue(font, "Size", vSize);
font->Release();
return ret;
}
bool MSSheet::Print() {
if (!Sheet)
return false;
bool ret = Ole::Method(Sheet, "PrintOut");
return ret;
}
enum XLSheetTypes {xlWorksheet = -4167, xlChart = -4109, xlExcel4MacroSheet = 3, xlExcel4IntlMacroSheet = 4};
bool MSSheet::InsertTab(String name) { // Insert tab after the last
if (!App)
return false;
if (!(Sheet = Ole::GetObject(Ole::GetObject(App, "Sheets"), "Add")))
return false;
VariantOle vName;
vName.BString(name);
if(!Ole::SetValue(Sheet, "Name", vName))
return false;
//return true;
VariantOle vOptional;
vOptional.Optional();
ObjectOle lastSheet;
VariantOle vId;
vId.Int(GetNumTabs());
if (!(lastSheet = Ole::GetObject(App, "Sheets", vId)))
return false;
VariantOle vAfter;
vAfter.ObjectOle(lastSheet);
bool ret = Ole::Method(Sheet, "Move", vAfter, vOptional); // Apending tab after last tab
lastSheet->Release();
return ret;
}
bool MSSheet::SetColor(String cell, Color color) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetColor(col, row, color);
}
bool MSSheet::SetColor(int col, int row, Color color) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
VariantOle cvalue;
cvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Font"), "Color", cvalue);
}
bool MSSheet::SetColor(Color color) {
if (!Range)
return false;
VariantOle cvalue;
cvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Ole::GetObject(Range, "Font"), "Color", cvalue);
}
double MmToPointsWidth(double mm) {
return 0.51155*mm - 0.7502;
}
double MmToPointsHeight(double mm) {
return 2.83018*mm;
}
bool MSSheet::SetRowHeight(int row, double height) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(1);
y.Int4(row);
VariantOle cvalue;
cvalue.Int(int(MmToPointsHeight(height)));
return Ole::SetValue(Ole::GetObject(Sheet, "Cells", x, y), "RowHeight", cvalue);
}
bool MSSheet::SetColWidth(int col, double width) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(1);
VariantOle cvalue;
cvalue.Int(int(MmToPointsWidth(width)));
return Ole::SetValue(Ole::GetObject(Sheet, "Cells", x, y), "ColumnWidth", cvalue);
}
bool MSSheet::SetBackColor(String cell, Color color) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetColor(col, row, color);
}
bool MSSheet::SetBackColor(int col, int row, Color color) {
if (!Sheet)
return false;
VariantOle x, y;
x.Int4(col);
y.Int4(row);
VariantOle cvalue;
cvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Ole::GetObject(Ole::GetObject(Sheet, "Cells", x, y), "Interior"), "Color", cvalue);
}
bool MSSheet::SetBackColor(Color color) {
if (!Range)
return false;
VariantOle cvalue;
cvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Ole::GetObject(Range, "Interior"), "Color", cvalue);
}
bool MSSheet::ChooseTab(String name) {
if (!App)
return false;
VariantOle vName;
vName.BString(name);
if (!(Sheet = Ole::GetObject(App, "Sheets", vName)))
return false;
return Ole::Method(Sheet, "select");
}
bool MSSheet::ChooseTab(int index) {
if (!App)
return false;
VariantOle vId;
vId.Int(index+1);
if (!(Sheet = Ole::GetObject(App, "Sheets", vId)))
return false;
return Ole::Method(Sheet, "select");
}
bool MSSheet::RemoveTab(String name) {
if (!App)
return false;
ObjectOle DelSheet;
VariantOle vName;
vName.BString(name);
if (!(DelSheet = Ole::GetObject(App, "Sheets", vName)))
return false;
bool ret = Ole::Method(DelSheet, "delete");
DelSheet->Release();
return ret;
}
bool MSSheet::RemoveTab(int index) {
if (!App)
return false;
ObjectOle DelSheet;
VariantOle vId;
vId.Int(index+1);
if (!(DelSheet = Ole::GetObject(App, "Sheets", vId)))
return false;
bool ret = Ole::Method(DelSheet, "delete");
DelSheet->Release();
return ret;
}
int MSSheet::GetNumTabs() {
if (!App)
return -1;
return Ole::GetValue(Ole::GetObject(App, "Sheets"), "count");
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INITBLOCK {
PluginRegister(OfficeDoc, MSDoc, "Microsoft");
}
MSDoc::MSDoc() {
App = Docs = Doc = Selection = NULL;
quit = false;
App = Ole::CreateObject("Word.Application");
if (!(Docs = Ole::GetObject(App, "Documents"))) {
LOG("Word document not loaded properly");
return;
}
}
MSDoc::~MSDoc() {
if (Selection)
Selection->Release();
if (Doc)
Doc->Release();
if (Docs)
Docs->Release();
if (App) {
Quit();
App->Release();
}
Ole::Close();
}
bool MSDoc::SetVisible(bool visible) {
if (!Docs)
return false;
VariantOle vVisible;
vVisible.Int4(visible? 1: 0);
return Ole::SetValue(App, "Visible", vVisible);
}
bool MSDoc::IsAvailable() {
ObjectOle app = Ole::CreateObject("Word.Application");
if (!app)
return false;
else {
app->Release();
return true;
}
}
bool MSDoc::SetSaved(bool saved) {
if (!Doc)
return false;
VariantOle vSaved;
vSaved.Int4(saved? 1: 0);
return Ole::SetValue(Doc, "Saved", vSaved);
}
bool MSDoc::Quit() {
if (!quit) {
quit = true;
return Ole::Method(App, "Quit");
}
return true;
}
bool MSDoc::AddDoc(bool visible) {
if (!Docs)
return false;
if (!(Doc = Ole::MethodGet(Docs, "Add")))
return false;
if(!(Selection = Ole::GetObject(App, "Selection")))
return false;
SetVisible(visible);
return true;
}
bool MSDoc::OpenDoc(String fileName, bool visible) {
if (!Docs)
return false;
VariantOle vFileName;
vFileName.BString(fileName);
if (!(Doc = Ole::MethodGet(Docs, "Open", vFileName)))
return false;
if(!(Selection = Ole::GetObject(App, "Selection")))
return false;
SetVisible(visible);
return true;
}
bool MSDoc::SaveAs(String fileName, String type) {
if (!Doc)
return false;
if (type[0] == '.')
type = type.Mid(1);
fileName = ForceExt(fileName, "." + type);
VariantOle vFileName, vType;
vFileName.BString(fileName);
if (type == "rtf")
vType.Int(6);
else if (type == "html")
vType.Int(8);
else if (type == "txt")
vType.Int(2);
else if (type == "docx")
vType.Int(13);
else // doc
vType.Int(0);
int ret = Ole::Method(Doc, "SaveAs", vType, vFileName);
return (bool)ret;
}
bool MSDoc::WriteText(String value) {
if (!Selection)
return false;
VariantOle val;
val.BString(value);
return Ole::Method(Selection, "TypeText", val);
}
bool MSDoc::SetFont(String type, int size) {
ObjectOle font;
if(!(font = Ole::GetObject(Selection, "Font")))
return false;
VariantOle vType;
vType.BString(type);
if(!Ole::SetValue(font, "Name", vType))
return false;
VariantOle vSize;
vSize.Int(size);
if(!Ole::SetValue(font, "Size", vSize))
return false;
return true;
}
bool MSDoc::SetBold(bool bold) {
VariantOle vBold;
vBold.Bool(bold);
if(!Ole::SetValue(Ole::GetObject(Selection, "Font"), "Bold", vBold))
return false;
return true;
}
bool MSDoc::SetItalic(bool italic) {
VariantOle vItalic;
vItalic.Bool(italic);
if(!Ole::SetValue(Ole::GetObject(Selection, "Font"), "Italic", vItalic))
return false;
return true;
}
bool MSDoc::Print() {
if (!Docs && !Doc)
return false;
bool ret = Ole::Method(Doc, "PrintOut");
return ret;
}
bool MSDoc::Select() {
return Ole::Method(Selection, "WholeStory");
}
// Some tricks as Ole Replace does not work properly for texts to replace longer than
// about 250 chars and for some special chars
bool MSDoc::Replace(String search, String _replace) {
String replace = CleanString(_replace);
replace.Replace("^", " ");
replace.Replace("\r", ""); // To remove squares
String replaceSubset;
while (replace.GetCount() > 200) {
replaceSubset = replace.Left(200);
replaceSubset.Cat(search);
replace = replace.Right(replace.GetCount() - 200);
replaceSubset.Replace("\n", "^l");
if (!ReplaceSubset(search, replaceSubset))
return false;
}
replace.Replace("\n", "^l");
return ReplaceSubset(search, replace);
}
String MSDoc::CleanString(String str) { // Clean chars in String
String ret;
String valid = ">=<ºª%€&()$1234567890áéíóúÁÉÍÓÚñÑçÇ,.,:-_/¿?+*[]{}'\"\r\n";
for (int i = 0; i < str.GetCount(); ++i) {
int s = str[i];
if (IsLetter(s) || valid.Find(s) >= 0)
ret.Cat(s);
}
return ret;
}
bool MSDoc::ReplaceSubset(String search, String replace) {
ObjectOle find;
if (!(find = Ole::GetObject(Selection, "Find")))
return false;
if(!Ole::Method(find, "ClearFormatting")) // Selection.Find.ClearFormatting
return false;
VariantOle vFindText;
vFindText.BString(search);
VariantOle vMatchCase;
vMatchCase.Bool(false);
VariantOle vMatchWholeWord;
vMatchWholeWord.Bool(false);
VariantOle vMatchWildcards;
vMatchWildcards.Bool(false);
VariantOle vMatchSoundsLike;
vMatchSoundsLike.Bool(false);
VariantOle vMatchAllWordForms;
vMatchAllWordForms.Bool(false);
VariantOle vForward;
vForward.Bool(true);
VariantOle vWrap;
vWrap.Int(wdFindContinue);
VariantOle vFormat;
vFormat.Bool(false);
VariantOle vReplaceWith;
vReplaceWith.BString(replace);
VariantOle vReplace;
vReplace.Int(wdReplaceAll);
return Ole::Method(find, "Execute", vReplace, vReplaceWith, vFormat, vWrap, vForward, vMatchAllWordForms, vMatchSoundsLike, vMatchWildcards, vMatchWholeWord, vMatchCase, vFindText);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class OOo {
public:
static ObjectOle MakePropertyValue(String name, ::Value value) {
ObjectOle ServiceManager;
if (!(ServiceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return NULL;
ObjectOle Struct;
VariantOle vstr;
vstr.BString("com.sun.star.beans.PropertyValue");
if (!(Struct = Ole::MethodGet(ServiceManager, "Bridge_GetStruct", vstr)))
return NULL;
VariantOle vname, vvalue;
vname.BString(name);
if (!Ole::SetValue(Struct, "Name", vname))
return NULL;
vvalue.Value(value);
if (!Ole::SetValue(Struct, "Value", vvalue))
return NULL;
return Struct;
}
static ObjectOle MakePropertyValue(String name, VariantOle &vvalue) {
ObjectOle ServiceManager;
if (!(ServiceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return NULL;
ObjectOle Struct;
VariantOle vstr;
vstr.BString("com.sun.star.beans.PropertyValue");
if (!(Struct = Ole::MethodGet(ServiceManager, "Bridge_GetStruct", vstr)))
return NULL;
VariantOle vname/*, vvalue*/;
vname.BString(name);
if (!Ole::SetValue(Struct, "Name", vname))
return NULL;
//vvalue.Value(value);
if (!Ole::SetValue(Struct, "Value", vvalue))
return NULL;
return Struct;
}
static String ConvertToUrl(String strFile) {
String ret;
String c;
for (int i = 0; i < strFile.GetCount(); ++i) {
if (strFile[i] >= 123)
c = "%" + Format("%x", strFile[i]);
else {
switch (strFile[i]) {
case 9: c = "%09"; break;
case 13: c = "%0d"; break;
case 10: c = "%0a"; break;
case 32: case 33: case 34: case 35: case 37: case 38: case 39: case 40: case 41: case 43:
case 44: case 59: case 60: case 61: case 62: case 63: case 91: case 93: case 94: case 96:
c = "%" + Format("%x", strFile[i]); break;
case '\\': c = "/"; break;
case ':': c = "|"; break;
default: c = strFile.Mid(i, 1);
}
}
ret.Cat(c);
}
return "file:///" + ret;
}
static ObjectOle CreateUnoService(String strServiceName) {
ObjectOle ServiceManager;
if (!(ServiceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return NULL;
VariantOle vService;
vService.BString(strServiceName);
return Ole::MethodGet(ServiceManager, "createInstance", vService);
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INITBLOCK {
PluginRegister(OfficeSheet, OPENSheet, "Open");
}
OPENSheet::OPENSheet() {
ServiceManager = CoreReflection = Desktop = Document = Sheets = Sheet = Cell = Range = NULL;
selectedAll = false;
quit = false;
// The service manager is always the starting point
// If there is no office running then an office is started up
ObjectOle ServiceManager;
if (!(ServiceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return;
// Create the CoreReflection service that is later used to create structs
ObjectOle CoreReflection;
VariantOle vInstance;
vInstance.BString("com.sun.star.reflection.CoreReflection");
if (!(CoreReflection = Ole::MethodGet(ServiceManager, "createInstance", vInstance)))
return;
// Create the Desktop
VariantOle vDesktop;
vDesktop.BString("com.sun.star.frame.Desktop");
if (!(Desktop = Ole::MethodGet(ServiceManager, "createInstance", vDesktop)))
return;
}
OPENSheet::~OPENSheet() {
if (Cell)
Cell->Release();
if (Range)
Range->Release();
if (Sheet)
Sheet->Release();
if (Sheets)
Sheets->Release();
if (Document)
Document->Release();
if (Desktop) {
Quit();
Desktop->Release();
}
if (CoreReflection)
CoreReflection->Release();
if (ServiceManager)
ServiceManager->Release();
}
bool OPENSheet::IsAvailable() {
ObjectOle serviceManager;
if (!(serviceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return false;
else {
serviceManager->Release();
return true;
}
}
bool OPENSheet::SetSaved(bool saved) {
VariantOle vval;
vval.Bool(!saved); // Modified is the opposite to saved
return Ole::Method(Document, "setModified", vval);
}
bool OPENSheet::Quit() {
if (!quit) {
quit = true;
return Ole::Method(Desktop, "Terminate");
}
return true;
}
bool OPENSheet::InsertTab(String name) {
if (!Sheets)
return false;
VariantOle vStr;
vStr.BString("com.sun.star.sheet.Spreadsheet");
if (!(Sheet = Ole::MethodGet(Document, "createInstance", vStr)))
return false;
vStr.BString(name);
VariantOle vsheet;
vsheet.ObjectOle(Sheet);
if (!(Ole::Method(Sheets, "insertByName", vsheet, vStr)))
return false;
// Set tab as active
ObjectOle View;
if (!(View = Ole::MethodGet(Document, "getCurrentController")))
return false;
VariantOle vSheet;
vSheet.ObjectOle(Sheet);
return Ole::SetValue(View, "ActiveSheet", vSheet);
}
bool OPENSheet::ChooseTab(String name) {
if (!Sheets)
return false;
VariantOle vStr;
vStr.BString(name);
if (!(Sheet = Ole::MethodGet(Sheets, "getByName", vStr)))
return false;
// Set tab as active
ObjectOle View;
if (!(View = Ole::MethodGet(Document, "getCurrentController")))
return false;
VariantOle vSheet;
vSheet.ObjectOle(Sheet);
return Ole::SetValue(View, "ActiveSheet", vSheet);
}
bool OPENSheet::ChooseTab(int index) {
if (!Sheets)
return false;
VariantOle vId;
vId.Int(index);
if (!(Sheet = Ole::MethodGet(Sheets, "getByIndex", vId)))
return false;
// Set tab as active
ObjectOle View;
if (!(View = Ole::MethodGet(Document, "getCurrentController")))
return false;
VariantOle vSheet;
vSheet.ObjectOle(Sheet);
return Ole::SetValue(View, "ActiveSheet", vSheet);
}
bool OPENSheet::RemoveTab(String name) {
if (!Sheets)
return false;
VariantOle vStr;
vStr.BString(name);
if (!Ole::Method(Sheets, "removeByName", vStr))
return false;
return true;
}
bool OPENSheet::RemoveTab(int index) {
if (!Sheets)
return false;
VariantOle vId;
vId.Int(index);
if (!Ole::Method(Sheets, "removeByIndex", vId))
return false;
return true;
}
int OPENSheet::GetNumTabs() {
if (!Sheets)
return -1;
Value count;
count = Ole::GetValue(Sheets, "getCount");
return count;
}
bool OPENSheet::AddSheet(bool visible) {
if (!Desktop)
return false;
VariantOle vArray;
vArray.ArrayDim(1);
VariantOle vobject;
vobject.ObjectOle(OOo::MakePropertyValue("Hidden", true));
vArray.ArraySetVariant(1, vobject);
VariantOle vFile;
vFile.BString("_blank");
VariantOle vSize;
vSize.Int4(0);
VariantOle vDocument;
vDocument.BString("private:factory/scalc");
if (!(Document = Ole::MethodGet(Desktop, "loadComponentFromURL", vArray, vSize, vFile, vDocument)))
return false;
if (!(Sheets = Ole::MethodGet(Document, "getSheets")))
return false;
if (!visible)
SetVisible(visible);
return ChooseTab(0); // Select the first tab
}
bool OPENSheet::OpenSheet(String fileName, bool visible) {
if (!Desktop)
return false;
VariantOle vArray;
vArray.ArrayDim(0);
VariantOle vFile;
vFile.BString("_blank");
VariantOle vSize;
vSize.Int4(0);
VariantOle vDocument;
vDocument.BString(OOo::ConvertToUrl(fileName));
if (!(Document = Ole::MethodGet(Desktop, "loadComponentFromURL", vArray, vSize, vFile, vDocument)))
return false;
if (!(Sheets = Ole::MethodGet(Document, "getSheets")))
return false;
if (!visible)
SetVisible(visible);
return ChooseTab(0); // Select the first tab
}
// Problem: It does hidden but not set visible again the window !!!
bool OPENSheet::SetVisible(bool visible) {
if (!Document)
return false;
ObjectOle DocCtrl;
if (!(DocCtrl = Ole::MethodGet(Document, "getCurrentController")))
return false;
ObjectOle DocFrame;
if (!(DocFrame = Ole::MethodGet(DocCtrl, "getFrame")))
return false;
ObjectOle DocWindow;
if (!(DocWindow = Ole::MethodGet(DocFrame, "getContainerWindow")))
return false;
VariantOle vvisible;
vvisible.Bool(visible);
return Ole::Method(DocWindow, "setVisible", vvisible);
}
bool OPENSheet::Select(String range) {
if (!Sheet)
return false;
VariantOle vrange;
vrange.BString(range);
if (!(Range = Ole::MethodGet(Sheet, "getCellRangeByName", vrange)))
return false;
return true;
}
bool OPENSheet::Select(int fromX, int fromY, int toX, int toY) {
if (!Sheet)
return false;
VariantOle vX1, vY1, vX2, vY2;
vX1.Int(fromX-1); // Comienza en 0
vY1.Int(fromY-1);
vX2.Int(toX-1); // Comienza en 0
vY2.Int(toY-1);
if (!(Range = Ole::MethodGet(Sheet, "getCellRangeByPosition", vY2, vX2, vY1, vX1)))
return false;
selectedAll = false;
return true;
}
bool OPENSheet::Select() {
if (!Sheet)
return false;
selectedAll = true;
return true;
}
void OPENSheet::DefMatrix(int width, int height) {
return;
}
void OPENSheet::SetMatrixValue(int x, int y, ::Value value) {
return;
}
bool OPENSheet::FillSelectionMatrix() {
return false;
}
bool OPENSheet::Replace(Value search, Value replace) {
if (!Sheet)
return false;
ObjectOle Search;
if (!(Search = Ole::MethodGet(Sheet, "createReplaceDescriptor")))
return false;
VariantOle vsearch, vreplace;
vsearch.BString(search);
Ole::Method(Search, "setSearchString", vsearch);
vreplace.BString(replace);
Ole::Method(Search, "setReplaceString", vreplace);
VariantOle vsrep;
vsrep.ObjectOle(Search);
ObjectOle *data;
if (selectedAll) {
if (!Sheet)
return false;
data = &Sheet;
} else {
if (!Range)
return false;
data = &Range;
}
if (!Ole::Method(*data, "replaceAll", vsrep))
return false;
return true;
}
Value OPENSheet::GetValue(int col, int row) {
if (!SelCell(col, row))
return false;
return Ole::GetValue(Cell, "getFormula"); // Also valid getValue and getString
}
Value OPENSheet::GetText(int col, int row) {
if (!SelCell(col, row))
return false;
return Ole::GetValue(Cell, "getString"); // Also valid getValue and getString
}
Value OPENSheet::GetValue(String cell) {
int row, col;
OfficeSheet::CellToColRow(cell, col, row);
return GetValue(col, row);
}
Value OPENSheet::GetText(String cell) {
int row, col;
OfficeSheet::CellToColRow(cell, col, row);
return GetText(col, row);
}
bool OPENSheet::SaveAs(String fileName, String type) {
if (!Document)
return false;
if (type[0] == '.')
type = type.Mid(1);
fileName = ForceExt(fileName, "." + type);
VariantOle vFileName;
vFileName.BString(OOo::ConvertToUrl(fileName));
String filter;
if (type == "xls")
filter = "MS Excel 97";
else if (type == "pxl")
filter = "Pocket Excel";
else if (type == "html")
filter = "HTML (StarCalc)";
else if (type == "txt")
filter = "Text - txt - csv (StarCalc)";
else if (type == "pdf")
filter = "calc_pdf_Export";
else if (type == "ods")
filter = "";
else
return false;
VariantOle vArraySave;
bool ret;
if (filter.IsEmpty()) {
vArraySave.ArrayDim(0);
ret = Ole::Method(Document, "storeToURL", vArraySave, vFileName);
} else {
VariantOle vArg;
vArg.ObjectOle(OOo::MakePropertyValue("FilterName", filter));
vArraySave.ArrayDim(1);
vArraySave.ArraySetVariant(1, vArg);
ret = Ole::Method(Document, "storeToURL", vArraySave, vFileName);
}
if (ret)
SetSaved(true);
return ret;
}
bool OPENSheet::SelCell(int x, int y)
{
if (!Sheet)
return false;
VariantOle vX, vY;
vX.Int(x-1); // Comienza en 0
vY.Int(y-1);
if (!(Cell = Ole::MethodGet(Sheet, "getCellByPosition", vY, vX)))
return false;
return true;
}
bool OPENSheet::SetValue(String cell, Value value) { // cell in textual format like "B14"
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetValue(col, row, value);
}
bool OPENSheet::SetValue(int col, int row, Value value) {
if (!SelCell(col, row))
return false;
VariantOle vText;
vText.Value(value);
if (value.Is<String>() || value.Is<Date>() || value.Is<Time>())
return Ole::Method(Cell, "setFormula", vText);
else
return Ole::Method(Cell, "setValue", vText);
}
bool OPENSheet::SetValue(Value value) {
if(!Range)
return false;
VariantOle vText;
vText.Value(value);
if (value.Is<String>() || value.Is<Date>() || value.Is<Time>())
return Ole::Method(Range, "setFormula", vText);
else
return Ole::Method(Range, "setValue", vText);
}
bool OPENSheet::SetHyperlink(String cell, String address, String text) { // cell in textual format like "B14"
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetHyperlink(col, row, address, text);
}
bool OPENSheet::SetHyperlink(int col, int row, String address, String text) {
/* if (!SelCell(col, row))
return false;
VariantOle vText;
vText.Value(value);
if (value.Is<String>() || value.Is<Date>() || value.Is<Time>())
return Ole::Method(Cell, "setFormula", vText);
else
return Ole::Method(Cell, "setValue", vText);
*/
return false;
}
bool OPENSheet::SetHyperlink(String address, String text) {
/* if(!Range)
return false;
VariantOle vText;
vText.Value(value);
if (value.Is<String>() || value.Is<Date>() || value.Is<Time>())
return Ole::Method(Range, "setFormula", vText);
else
return Ole::Method(Range, "setValue", vText);
*/
return false;
}
bool OPENSheet::SetItalic(String cell, bool italic) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetItalic(col, row, italic);
}
bool OPENSheet::SetItalic(int col, int row, bool italic) {
if (!SelCell(col, row))
return false;
VariantOle vproperty, vvalue;
vproperty.BString("CharPosture");
if (italic)
vvalue.Int(2);
else
vvalue.Int(0);
return Ole::SetValue(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetItalic(bool italic) {
VariantOle vvalue;
if (italic)
vvalue.Int(2);
else
vvalue.Int(0);
return Ole::SetValue(Range, "CharPosture", vvalue);
}
bool OPENSheet::SetBold(String cell, bool bold) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetBold(col, row, bold);
}
bool OPENSheet::SetBold(int col, int row, bool bold) {
if (!SelCell(col, row))
return false;
VariantOle vproperty, vvalue;
vproperty.BString("CharBold");
vvalue.Bool(bold);
return Ole::SetValue(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetBold(bool bold) {
VariantOle vvalue;
if (bold)
vvalue.Int(150);
else
vvalue.Int(100);
return Ole::SetValue(Range, "CharWeight", vvalue);
}
bool OPENSheet::SetUnderline(String cell, bool underline) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetBold(col, row, underline);
}
bool OPENSheet::SetUnderline(int col, int row, bool underline) {
if (!SelCell(col, row))
return false;
VariantOle vproperty, vvalue;
vproperty.BString("CharUnderline");
vvalue.Bool(underline);
return Ole::SetValue(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetUnderline(bool underline) {
VariantOle vvalue;
if (underline)
vvalue.Int(1); // 2 is doble underline
else
vvalue.Int(0);
return Ole::SetValue(Range, "CharUnderline", vvalue);
}
bool OPENSheet::SetHorizAlignment(String cell, int alignment) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetHorizAlignment(col, row, alignment);
}
bool OPENSheet::SetHorizAlignment(int col, int row, int alignment) {
if (!SelCell(col, row))
return false;
if (alignment < 1 || alignment >= OfficeSheet::MAX_JUSTIFY)
return false;
int justifyConst[] = {1, 2, 3, 4, 1, 3};
VariantOle vvalue;
vvalue.Int(justifyConst[alignment]);
return Ole::SetValue(Cell, "HoriJustify", vvalue);
}
bool OPENSheet::SetVertAlignment(String cell, int alignment) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetVertAlignment(col, row, alignment);
}
bool OPENSheet::SetVertAlignment(int col, int row, int alignment) {
if (!SelCell(col, row))
return false;
if (alignment < 1 || alignment >= OfficeSheet::MAX_JUSTIFY)
return false;
int justifyConst[] = {1, 2, 3, 4, 1, 3};
VariantOle vvalue;
vvalue.Int(justifyConst[alignment]);
return Ole::SetValue(Cell, "VertJustify", vvalue);
}
bool OPENSheet::SetBorder(int borderIndx, int lineStyle, int weight, Color color) {
if (!Range)
return false;
return false; // Not implemented yet :(
/* This is an unsuccesful test
VariantOle vBorder;
vBorder.ArrayDim(4);
vBorder.ArraySetValue(0, 0);
vBorder.ArraySetValue(1, 0);
vBorder.ArraySetValue(2, 80);
vBorder.ArraySetValue(3, 0);
VariantOle vNoBorder;
vNoBorder.ArrayDim(4);
vNoBorder.ArraySetValue(0, 0);
vNoBorder.ArraySetValue(1, 0);
vNoBorder.ArraySetValue(2, 0);
vNoBorder.ArraySetValue(3, 0);
VariantOle vArg;
VariantOle vArraySave;
vArraySave.ArrayDim(8);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.LeftBorder", vBorder));
vArraySave.ArraySetVariant(1, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.LeftDistance", 0));
vArraySave.ArraySetVariant(2, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.RightBorder", vBorder));
vArraySave.ArraySetVariant(3, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.RightDistance", 0));
vArraySave.ArraySetVariant(4, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.TopBorder", vBorder));
vArraySave.ArraySetVariant(5, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.TopDistance", 0));
vArraySave.ArraySetVariant(6, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.BottomBorder", vBorder));
vArraySave.ArraySetVariant(7, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("BorderOuter.BottomDistance", 0));
vArraySave.ArraySetVariant(8, vArg);
if (!Ole::Method(Range, "BorderOuter", vArraySave))
return false;
*/
}
bool OPENSheet::SetBorder(int col, int row, int borderIndx, int lineStyle, int weight, Color color) {
if (!Sheet)
return false;
return false; // Not implemented yet :(
}
bool OPENSheet::SetFont(String cell, String name, int size) {
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetFont(col, row, name, size);
}
bool OPENSheet::SetFont(int col, int row, String name, int size) {
if (!SelCell(col, row))
return false;
VariantOle vproperty, vvalue;
vproperty.BString("CharFontName");
vvalue.BString(name);
Ole::Method(Cell, "setPropertyValue", vvalue, vproperty);
vproperty.BString("CharHeight");
vvalue.Int(size);
return Ole::Method(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetFont(String name, int size) {
VariantOle vvalue;
vvalue.BString(name);
Ole::SetValue(Range, "CharFontName", vvalue);
vvalue.Int(size);
return Ole::SetValue(Range, "CharHeight", vvalue);
}
bool OPENSheet::SetColor(String cell, Color color) { // 2 Centered
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetColor(col, row, color);
}
bool OPENSheet::SetColor(int col, int row, Color color) {
if (!SelCell(col, row))
return false;
return SetColor(color);
}
bool OPENSheet::SetColor(Color color) {
VariantOle vproperty, vvalue;
vproperty.BString("CellColor");
vvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetBackColor(String cell, Color color) { // 2 Centered
int col, row;
OfficeSheet::CellToColRow(cell, col, row);
return SetBackColor(col, row, color);
}
bool OPENSheet::SetBackColor(int col, int row, Color color) {
if (!SelCell(col, row))
return false;
return SetBackColor(color);
}
bool OPENSheet::SetBackColor(Color color) {
VariantOle vproperty, vvalue;
vproperty.BString("CellBackColor");
vvalue.Int4(RGB(color.GetR(), color.GetG(), color.GetB()));
return Ole::SetValue(Cell, "setPropertyValue", vvalue, vproperty);
}
bool OPENSheet::SetFormat(String format) {
int value;
if (format == "integer")
value = 1;
else if (format == "float")
value = 2;
else if (format == "date")
value = 37;
else if (format == "time")
value = 41;
else if (format == "datetime")
value = 51;
else
return false;
VariantOle vvalue;
vvalue.Int(value);
return Ole::SetValue(Range, "NumberFormat", vvalue);
}
bool OPENSheet::SetColWidth(int col, double width) {
ObjectOle Columns;
if (!(Columns = Ole::MethodGet(Sheet, "getColumns")))
return false;
ObjectOle Column;
VariantOle vvalue;
vvalue.Int(col);
if (!(Column = Ole::MethodGet(Columns, "getByIndex", vvalue)))
return false;
vvalue.Int(int(width*100));
return Ole::SetValue(Column, "Width", vvalue);
}
bool OPENSheet::SetRowHeight(int row, double height) {
ObjectOle Rows;
if (!(Rows = Ole::MethodGet(Sheet, "getRows")))
return false;
ObjectOle Row;
VariantOle vvalue;
vvalue.Int(row);
if (!(Row = Ole::MethodGet(Rows, "getByIndex", vvalue)))
return false;
vvalue.Int(int(height*100));
return Ole::SetValue(Row, "Height", vvalue);
}
bool OPENSheet::Print() {
VariantOle vArrayPrint;
vArrayPrint.ArrayDim(1);
VariantOle vArg;
vArg.ObjectOle(OOo::MakePropertyValue("CopyCount", 1));
vArrayPrint.ArraySetVariant(1, vArg);
return Ole::Method(Document, "print", vArrayPrint);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INITBLOCK {
PluginRegister(OfficeDoc, OPENDoc, "Open");
}
OPENDoc::OPENDoc() {
ServiceManager = CoreReflection = Desktop = Document = Text = Cursor = NULL;
quit = false;
// The service manager is always the starting point
// If there is no office running then an office is started up
ObjectOle ServiceManager;
if (!(ServiceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return;
// Create the CoreReflection service that is later used to create structs
ObjectOle CoreReflection;
VariantOle vInstance;
vInstance.BString("com.sun.star.reflection.CoreReflection");
if (!(CoreReflection = Ole::MethodGet(ServiceManager, "createInstance", vInstance)))
return;
// Create the Desktop
VariantOle vDesktop;
vDesktop.BString("com.sun.star.frame.Desktop");
if (!(Desktop = Ole::MethodGet(ServiceManager, "createInstance", vDesktop)))
return;
}
OPENDoc::~OPENDoc() {
if (Cursor)
Cursor->Release();
if (Text)
Text->Release();
if (Document)
Document->Release();
if (Desktop) {
Quit();
Desktop->Release();
}
if (CoreReflection)
CoreReflection->Release();
if (ServiceManager)
ServiceManager->Release();
}
bool OPENDoc::IsAvailable() {
ObjectOle serviceManager;
if (!(serviceManager = Ole::CreateObject("com.sun.star.ServiceManager")))
return false;
else {
serviceManager->Release();
return true;
}
}
bool OPENDoc::AddDoc(bool visible) {
if (!Desktop)
return false;
VariantOle vArray;
vArray.ArrayDim(1);
VariantOle vobject;
vobject.ObjectOle(OOo::MakePropertyValue("Hidden", true));
vArray.ArraySetVariant(1, vobject);
VariantOle vFile;
vFile.BString("_blank");
VariantOle vSize;
vSize.Int4(0);
VariantOle vDocument;
vDocument.BString("private:factory/swriter");
if (!(Document = Ole::MethodGet(Desktop, "loadComponentFromURL", vArray, vSize, vFile, vDocument)))
return false;
if (!visible)
SetVisible(visible);
// Create a text object
if (!(Text = Ole::MethodGet(Document, "getText")))
return false;
// Create a cursor object
if (!(Cursor = Ole::MethodGet(Text, "createTextCursor")))
return false;
return true;
}
bool OPENDoc::OpenDoc(String fileName, bool visible) {
if (!Desktop)
return false;
VariantOle vArray;
vArray.ArrayDim(1);
VariantOle vobject;
vobject.ObjectOle(OOo::MakePropertyValue("Hidden", true));
vArray.ArraySetVariant(1, vobject);
VariantOle vFile;
vFile.BString("_blank");
VariantOle vSize;
vSize.Int4(0);
VariantOle vDocument;
vDocument.BString(OOo::ConvertToUrl(fileName));
if (!(Document = Ole::MethodGet(Desktop, "loadComponentFromURL", vArray, vSize, vFile, vDocument)))
return false;
if (!visible)
SetVisible(visible);
// Create a text object
if (!(Text = Ole::MethodGet(Document, "getText")))
return false;
// Create a cursor object
if (!(Cursor = Ole::MethodGet(Text, "createTextCursor")))
return false;
return true;
}
bool OPENDoc::SetVisible(bool visible) {
if (!Document)
return false;
ObjectOle DocCtrl;
if (!(DocCtrl = Ole::MethodGet(Document, "getCurrentController")))
return false;
ObjectOle DocFrame;
if (!(DocFrame = Ole::MethodGet(DocCtrl, "getFrame")))
return false;
ObjectOle DocWindow;
if (!(DocWindow = Ole::MethodGet(DocFrame, "getContainerWindow")))
return false;
VariantOle vvisible;
vvisible.Bool(visible);
return Ole::Method(DocWindow, "setVisible", vvisible);
}
/*bool OPENDoc::SetColor(Color col) {
VariantOle vColor;
vColor.BString("CharColor");
VariantOle vValue;
vValue.Int4(RGB(col.GetR(), col.GetG(), col.GetB()));
return Ole::Method(Cursor, "setPropertyValue", vValue, vColor);
}*/
bool OPENDoc::SetFont(String font, int size) {
VariantOle vFont;
vFont.BString("CharFontName");
VariantOle vValue;
vValue.BString(font);
Ole::Method(Cursor, "setPropertyValue", vValue, vFont);
VariantOle vHeight;
vHeight.BString("CharHeight");
vValue.Int(size);
return Ole::Method(Cursor, "setPropertyValue", vValue, vHeight);
}
bool OPENDoc::SetBold(bool bold) {
VariantOle vvalue;
if (bold)
vvalue.Int(150);
else
vvalue.Int(100);
return Ole::SetValue(Cursor, "CharWeight", vvalue);
}
bool OPENDoc::SetItalic(bool italic) {
VariantOle vvalue;
if (italic)
vvalue.Int(2);
else
vvalue.Int(0);
return Ole::SetValue(Cursor, "CharPosture", vvalue);
}
bool OPENDoc::WriteText(String str) {
VariantOle vFalse;
vFalse.Bool(false);
VariantOle vText;
vText.BString(str);
VariantOle vCursor;
vCursor.ObjectOle(Cursor);
return Ole::Method(Text, "insertString", vFalse, vText, vCursor);
}
bool OPENDoc::Select() { // Not used here
return true;
}
bool OPENDoc::Replace(String search, String replace)
{
ObjectOle Search;
if (!(Search = Ole::MethodGet(Document, "createReplaceDescriptor")))
return false;
VariantOle vsearch;
vsearch.BString(search);
Ole::Method(Search, "setSearchString", vsearch);
VariantOle vreplace;
vreplace.BString(replace);
Ole::Method(Search, "setReplaceString", vreplace);
VariantOle vsrep;
vsrep.ObjectOle(Search);
return Ole::Method(Document, "replaceAll", vsrep);
}
bool OPENDoc::Print() {
/* Sorry. This does not run
VariantOle vArrayPrintConf;
vArrayPrintConf.ArrayDim(3);
vArg.ObjectOle(OOo::MakePropertyValue("Printer", "Default")); // Pages "1-15; 18"
vArrayPrintConf.ArraySetVariant(1, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("PaperOrientation", "com.sun.star.view.PaperOrientation.PORTRAIT"));
vArrayPrintConf.ArraySetVariant(2, vArg);
vArg.ObjectOle(OOo::MakePropertyValue("PaperFormat", "com.sun.star.view.PaperFormat.A4"));
vArrayPrintConf.ArraySetVariant(3, vArg);
if (!(Ole::SetValue(Document, "SetPrinter", vArrayPrintConf)))
return false;
*/
VariantOle vArrayPrint;
vArrayPrint.ArrayDim(1);
VariantOle vArg;
vArg.ObjectOle(OOo::MakePropertyValue("CopyCount", 1));
vArrayPrint.ArraySetVariant(1, vArg);
// It runs
// vArg.ObjectOle(OOo::MakePropertyValue("Pages", "2")); // Pages "1-15; 18"
// vArrayPrint.ArraySetVariant(2, vArg);
return Ole::Method(Document, "print", vArrayPrint);
}
bool OPENDoc::SetSaved(bool saved) {
VariantOle vval;
vval.Bool(!saved); // Modified is the opposite to saved
return Ole::Method(Document, "setModified", vval);
}
bool OPENDoc::SaveAs(String fileName, String type) {
if (!Document)
return false;
if (type[0] == '.')
type = type.Mid(1);
fileName = ForceExt(fileName, "." + type);
VariantOle vFileName;
vFileName.BString(OOo::ConvertToUrl(fileName));
String filter;
if (type == "doc")
filter = "MS Word 97";
else if (type == "rtf")
filter = "Rich Text Format";
else if (type == "psw")
filter = "Pocket Word File";
else if (type == "html")
filter = "HTML (StarDoc)";
else if (type == "txt")
filter = "Text";
else if (type == "pdf")
filter = "writer_pdf_Export";
else if (type == "odt")
filter = "";
else
return false;
VariantOle vArraySave;
if (filter.IsEmpty())
vArraySave.ArrayDim(0);
else {
VariantOle vArg;
vArg.ObjectOle(OOo::MakePropertyValue("FilterName", filter));
vArraySave.ArrayDim(1);
vArraySave.ArraySetVariant(1, vArg);
}
return Ole::Method(Document, "storeToURL", vArraySave, vFileName);
}
bool OPENDoc::Quit() {
if (!quit) {
quit = true;
if (Document)
return Ole::Method(Document, "Dispose");
}
return true;
}