tdf#50916 : Calc : Dynamic column container

classic Classic list List threaded Threaded
16 messages Options
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

tdf#50916 : Calc : Dynamic column container

Hi All

I have made an attempt at making the column container relatively dynamic in
the hope of increasing the column limit to 16K. The patch I have made ( https://gist.github.com/dennisfrancis/ba7254405f77282214bb#file-lo16kcols-patch ) does not have the required "big" refactoring, and have just enough changes to make everything compile and pass
the unit tests. I was not sure whether to put this very incomplete version in gerrit.

The underlying data structure is now a std::vector whose size can dynamically move between
1K(min) and 16K(max). This is wrapped in a template class called ScColContainer which could be
used in places where fixed size (MAXCOLCOUNT) arrays are used. The underlying data structure
can be changed relatively easily inside this template class without breaking the methods/operator
signatures.

Before I begin further refactoring I would like to discuss the various possibilities of data structures
which you already have in mind, that could be used here instead of just a std::vector, and their merits, demerits etc..

In the current approach, the plan is to have the same performance guarantees for sheets upto 1K cols and for sheets greater 1K, allocate only the required number of columns and only iterate over the column range 0 to largest column present actually in the sheet, instead of iterating over a fixed col range (0 to MAXCOL).

Please point out any deficiencies, blockades with my current approach and indicate better methods.

Thanks for you time.

Regards,
Dennis




_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Markus Mohrhard Markus Mohrhard
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hey Dennis,

so I suppose it is my turn to respond. Maybe Eike and/or Kohei will jump in as well.

On Fri, Oct 9, 2015 at 2:14 AM, Dennis Francis <[hidden email]> wrote:
Hi All

I have made an attempt at making the column container relatively dynamic in
the hope of increasing the column limit to 16K. The patch I have made ( https://gist.github.com/dennisfrancis/ba7254405f77282214bb#file-lo16kcols-patch ) does not have the required "big" refactoring, and have just enough changes to make everything compile and pass
the unit tests. I was not sure whether to put this very incomplete version in gerrit.

The underlying data structure is now a std::vector whose size can dynamically move between
1K(min) and 16K(max). This is wrapped in a template class called ScColContainer which could be
used in places where fixed size (MAXCOLCOUNT) arrays are used. The underlying data structure
can be changed relatively easily inside this template class without breaking the methods/operator
signatures.

Before I begin further refactoring I would like to discuss the various possibilities of data structures
which you already have in mind, that could be used here instead of just a std::vector, and their merits, demerits etc..

In the current approach, the plan is to have the same performance guarantees for sheets upto 1K cols and for sheets greater 1K, allocate only the required number of columns and only iterate over the column range 0 to largest column present actually in the sheet, instead of iterating over a fixed col range (0 to MAXCOL).

Please point out any deficiencies, blockades with my current approach and indicate better methods.

Thanks for you time.

Regards,
Dennis



This is surely not what we had in mind. Basically you just wrote a wrapper around std::vector.

There are a number of items a new design need:

* decision whether to store all ScColumn instances or only filled ones

* a way to handle the increased memory load
** most likely limiting the number of initial columns

* a way to handle the performance impact of many columns
** most likely improving the iterations through all columns

* a better way to handle row formattings
** what happens if someone marks a whole row and formats it
** how to handle formatting for columns that were allocated after the user formatted the whole row

* most likely a way to store the last formatted column and the last column with content
** needs some inspecting which loops through the columns need which of the information


Most likely a few more that I have not in mind right now.

A simple high level design could be to use a std::vector<ScColumn*> and only allocate columns that really contain content or formatting. Additionally we'd need to introduce a way to store the format of a row. These row formats might not be visible to the user and would be just an internal way to handle the formatting for all not yet allocated columns.

Of course there might be other designs that work as well or better but any design needs to deal with at least the problems mentioned above.

Regards,
Markus


_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi Markus

Thanks for your valuable feedback !

1.
"""
A simple high level design could be to use a std::vector<ScColumn*> and only allocate columns that really contain content or formatting. Additionally we'd need to introduce a way to store the format of a row. These row formats might not be visible to the user and would be just an internal way to handle the formatting for all not yet allocated columns.
"""

Let me make sure I get this idea right -

The aCol member in ScTable is declared as :
std::vector<ScColumn*> aCol;  // Or can have wrapper on it own
and in the ScTable ctor aCol is init with a minimum number (or possibly 16K) of NULL pointer elements ie no ScColumn instance is allocated yet.
If we allocate space for all pointers in aCol vector then I think it might take around 128 KB just for pointers,
(point 1.A) so might want to allocate that too just when it is needed, hence avoid the need to keep a int var for keeping the index of last non null element.

While loading a sheet or user types in something in ith column for the first time, allocate ScColumn
if ( ! aCol[i] )
{
  aCol[i] = new ScColumn;
  // Apply any full row formattings to aCol[i]
}

2.
Correct me if I am wrong - I guess the formatting of each cell in a column is stored in pAttrArray member of ScColumn. So for storing full row formatting, we need
a data structure that map from row number to the formatting info. Definitely need your inputs and code pointers on this.



This is surely not what we had in mind. Basically you just wrote a wrapper around std::vector.

There are a number of items a new design need:

* decision whether to store all ScColumn instances or only filled ones
 
3. 
If we use just std::vector<ScColumn>, we have to allocate n ScColumns if there are totally n columns in the sheet including blank ones upto the last non-blank column.
If we use std::vector<ScColumn*> we need to allocate ScColumn's for only the non blank columns in the document - definitely better.


* a way to handle the increased memory load
** most likely limiting the number of initial columns
 
See point 1.

4.
* a way to handle the performance impact of many columns
** most likely improving the iterations through all columns

If we use std::vector<ScColumn>, We can trim the for loops to run from 0 up to current length of aCol.
If we use std::vector<ScColumn*>, We can trim the for loops to run from 0 up to current length of aCol and also skip running the inner logic whenever
aCol[i] == NULL, there by saving time, but not sure we can convert all column for loops like that offhand.
 

* a better way to handle row formattings
** what happens if someone marks a whole row and formats it
** how to handle formatting for columns that were allocated after the user formatted the whole row

See point 2.
 
* most likely a way to store the last formatted column and the last column with content
** needs some inspecting which loops through the columns need which of the information

See point 1.A, using this we can save time wasted on iterating over blank columns(aCol[i] == NULL).
Could you please explain why we need to remember "last formatted column" ?


Most likely a few more that I have not in mind right now.
 
Will surely wait for others to comment before proceeding any further.


Thanks,
Dennis




_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Markus Mohrhard Markus Mohrhard
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hey Dennis,

On Sat, Oct 10, 2015 at 3:30 PM, Dennis Francis <[hidden email]> wrote:
Hi Markus

Thanks for your valuable feedback !

1.
"""
A simple high level design could be to use a std::vector<ScColumn*> and only allocate columns that really contain content or formatting. Additionally we'd need to introduce a way to store the format of a row. These row formats might not be visible to the user and would be just an internal way to handle the formatting for all not yet allocated columns.
"""

Let me make sure I get this idea right -

The aCol member in ScTable is declared as :
std::vector<ScColumn*> aCol;  // Or can have wrapper on it own
and in the ScTable ctor aCol is init with a minimum number (or possibly 16K) of NULL pointer elements ie no ScColumn instance is allocated yet.
If we allocate space for all pointers in aCol vector then I think it might take around 128 KB just for pointers,
(point 1.A) so might want to allocate that too just when it is needed, hence avoid the need to keep a int var for keeping the index of last non null element.

Please don't allocate any pointers in advance. There is no value in that and it just causes higher memory load.

 

While loading a sheet or user types in something in ith column for the first time, allocate ScColumn
if ( ! aCol[i] )
{
  aCol[i] = new ScColumn;
  // Apply any full row formattings to aCol[i]
}

As we would not pre allocate the vector it would be more like:

if (i >= aCol.size())
{
    aCol.resize(i+1);
}
if (!aCol[i])
{
   aCol[i] = new ScColumn;
}

2.
Correct me if I am wrong - I guess the formatting of each cell in a column is stored in pAttrArray member of ScColumn. So for storing full row formatting, we need
a data structure that map from row number to the formatting info. Definitely need your inputs and code pointers on this.


Either that, which would be quite trivial or a way to have a concept where row and document formats are handled independently from the column formatting. E.g instead of our current design that stores a formatting entry even for a column that has default formatting only store entries for columns and cells that have been explicitly formatted. So if there is no column/cell formatting (they are basically the same) we would take the row formatting and if no row formatting is around take the document formatting.

Which of the two makes more sense would need some more design work.
 



This is surely not what we had in mind. Basically you just wrote a wrapper around std::vector.

There are a number of items a new design need:

* decision whether to store all ScColumn instances or only filled ones
 
3. 
If we use just std::vector<ScColumn>, we have to allocate n ScColumns if there are totally n columns in the sheet including blank ones upto the last non-blank column.
If we use std::vector<ScColumn*> we need to allocate ScColumn's for only the non blank columns in the document - definitely better.

The question is how likely it is to find such a case where it matters. The bigger problem would be that for std::vector<ScColumn> ScColumn needs to be either movable or copyable. Both are most likely things we are not prepared to do.
 


* a way to handle the increased memory load
** most likely limiting the number of initial columns
 
See point 1.

As mentioned there we should only allocate entries that are necessary. So an empty document basically just needs the size of an empty std::vector. Also ideas like the row formatting are part of the solution to this problem.
 

4.
* a way to handle the performance impact of many columns
** most likely improving the iterations through all columns

If we use std::vector<ScColumn>, We can trim the for loops to run from 0 up to current length of aCol.
If we use std::vector<ScColumn*>, We can trim the for loops to run from 0 up to current length of aCol and also skip running the inner logic whenever
aCol[i] == NULL, there by saving time, but not sure we can convert all column for loops like that offhand.

You need to skip vector entries that are NULL anyway.

Obviously you need to convert all loops as you have some problems otherwise.
 
 

* a better way to handle row formattings
** what happens if someone marks a whole row and formats it
** how to handle formatting for columns that were allocated after the user formatted the whole row

See point 2.
 
* most likely a way to store the last formatted column and the last column with content
** needs some inspecting which loops through the columns need which of the information

See point 1.A, using this we can save time wasted on iterating over blank columns(aCol[i] == NULL).
Could you please explain why we need to remember "last formatted column" ?

Depending on the design this happens directly or you need to do it indirectly. These comments where general comments without looking at any implementation. In the implementation with the std::vector<ScColumn*> this happens indirectly though std::vector<ScColumn*>size().

 The idea to store the last column with content might help us avoid looping through a lot of columns that are only formatted. It is not yet sure if that is really necessary.



Most likely a few more that I have not in mind right now.
 
Will surely wait for others to comment before proceeding any further.


The proposed design is based on a discussion between Kohei and met. Maybe Eike has some additional comments otherwise feel free to work on a design.
 


Thanks,
Dennis





_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Eike Rathke-2 Eike Rathke-2
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

In reply to this post by Markus Mohrhard
Hi,

On Saturday, 2015-10-10 00:05:11 +0200, Markus Mohrhard wrote:
> Most likely a few more that I have not in mind right now.

Additional caveats that sprang to mind:

* sizes and distribution of area listener slots
  * this currently is based on MAXCOLCOUNT values on compile time and
    there even exist preprocessor checks that ensure certain multiples
    of 16 so that things fit, see sc/source/core/data/bcaslot.cxx
  * distribution of slots is exponential starting from top left because
    it is assumed that the top left of a sheet is more populated than
    the far out bottom right
  * actual creation of slots is already dynamical, but the distribution
    algorithm may have to be reworked
  * if a user really needs and populates more than 1024 columns, having
    even larger slots in the far right probably slows down things when
    changes occur in that area

* named expressions that involve relative comlumn offsets
  * ugly stuff, because relative offsets wrap around the column edges
    * e.g. having defined a name on A2 to =A1 and using it on A1 will
      give =A1024 with 1024 columns
    * this because Excel does it ...
  * already a nightmare during import/export of documents that have
    different dimensions, because neither ODF nor OOXML or BIFF store
    the actual dimensions, they are only implicityl known by which
    program and version generated which file format
    * we'll probably have to change that and come up with file format
      extensions
    * none of the generators or readers so far handle dynamic column
      limits

* reference update procedures work with MAXCOL values
  * these would have to get the actual column maximum get passed in
  * BUT, references like 1:1 meaning the entire row would not know that
    a larger column suddenly is available, internally they currently
    store for example A1:AMJ1 and just know that it's the entire row and
    take it into account that the anchors are sticky when references are
    updated
    * probably range references need a "this is the last column" flag
    * if that changed, the next caveat kicks in: how to store in file
      format? An older release encountering A1:XXX1 when reading the
      file WILL fail on that
      * so a change will have to be carefully prepared and distributed
        over various releases to enable at least the two previous
        releases to handle such references

* if dynamically adding columns is made possible, increasing the columns
  would have to be done on *all* sheets, else all 3D addressing would be
  a nightmare


Just what I quickly came up with..

  Eike

--
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key "ID" 0x65632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Better use 64-bit 0x6A6CD5B765632D3A here is why: https://evil32.com/
Care about Free Software, support the FSFE https://fsfe.org/support/?erack

_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice

signature.asc (836 bytes) Download Attachment
Kohei Yoshida-6 Kohei Yoshida-6
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

So, I'm gonna reply to Eike's post, but my reply is not in response to
Eike's, but just a general idea I have on this subject.

I had already discussed this with Markus before he posted his, and his
post also reflects my view on this in general.

First off, allowing dynamic growth of column container is purely an
implementation detail i.e. at the UI level the column size should be
fixed.  What we aim to achieve is to not statically allocate column
instances for the max number of columns on launch.  Instead, grow the
allocated space based on how many columns store data.  On that front,
Markus already provided what needs to be done, and I believe Dennis
already gets it.

At higher level, there are two aspects to this.  One is improving the
storage efficiency of ScColumn, which I believe we already know what
needs to be done.

The other one is about improving algorithm used to access data stored in
ScColumn currently.  When you read through Calc's currently code, you'll
see a lot of code that looks like this:

        for (nCol=0; nCol<=MAXCOL; nCol++)
        {
            // do something here...
        }

In a lot of places we do go through the whole column array to get
something done.  That may be ok when the maximum column size is 1024,
but if we were to increase the max column size, we do need to do better
than this.

The idea about reworking the attribute storage by storing some of that
as row attributes or document attribute was about solving this with
regard to drawing cell attributes, by improving storage and algorithmic
efficiency of what is currently stored in ScAttrArray.

Aside from that, there are many other places where we could use
improvement.  Just grep through Calc's code for MAXCOL and find all
instances of for loops where we currently iterate from column 0 to
column MAXCOL, and try to remove that inefficiency, by perhaps moving
the data from ScColumn to somewhere else, or ....

That's the very high level overview of what needs to be done.  I guess
what I need to emphasize is that switching the storage for ScColumn is
just one piece of the puzzle; there are lots of other problems that need
to be resolved in order to make this all work.

The good news is that, this can (and perhaps should) be done
incrementally.  Going through each of the 0-to-MAXCOL-iterated for loops
and eliminating that one by one can be done one at a time.

That's all I have to say at the moment.  I admit this is a bit of an
abstract thinking, but I think what Markus and Eike already said should
provide enough specificity about this, so I'm just trying to add a bit
of a high level view.

Also, this will be an on-going process.  This is not going to be like
"if you do A, B and C it's okay to increase the column size and no
problems will occur".  Rather, we'll probably encounter lots of
performance issues that we'll have to spend some time fixing after the
column size is increased.

Kohei


_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Wols Lists Wols Lists
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

On 14/10/15 02:08, Kohei Yoshida wrote:
> Also, this will be an on-going process.  This is not going to be like
> "if you do A, B and C it's okay to increase the column size and no
> problems will occur".  Rather, we'll probably encounter lots of
> performance issues that we'll have to spend some time fixing after the
> column size is increased.

Just throwing an idea into the mix...

Howsabout a function that, on being given the cell co-ordinates, returns
a pointer to the cell. Force everything through that.

Okay, that's an extra level of indirection, that on a large spreadsheet
could cost a lot. But is it worth it in terms of memory saved? The
important point here is that you can change the in-memory storage of
your spreadsheet to match its characteristics.

If you have a small spreadsheet, you simply have a two dimensional array
of cells.

If you have say 100 cells with stuff in, in a spreadsheet that might be
1000x1000, you can have a lookup table that lists all the columns with
data, and within that all the rows that have data ...

I can't think of any more examples particularly. But if you have that
abstraction layer, you can optimise for different characteristics of
different spreadsheets.

(I'm coming at it from my database background, where Pick stores
everything as strings, and it's amazing how fast it actually finds stuff
even despite having to search sequentially through what is possibly a
long string, and how convenient it is to be able to use "proper" arrays
and "dynamic" arrays (delimited strings) together to optimise speed.)

As I say, this is just an idea, it might be a no-no, but if it can
optimise large sheets while not costing small sheets much, it could well
be worth it.

Cheers,
Wol
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Kohei Yoshida-6 Kohei Yoshida-6
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container



> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi All

I have submitted a prelim patch at https://gerrit.libreoffice.org/21620 following Kohei's suggestion of
solving this bug incrementally.

Thanks,
Dennis

On Wed, Oct 14, 2015 at 10:22 PM, Kohei Yoshida <[hidden email]> wrote:


> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice


_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi All

It has been quite a while since I worked on this bug. Lately I have been thinking about "a better way to handle row formattings".
In the current setting, if someone formats whole row, it is required that we have all columns from 0 to MAXCOL allocated, which is bad when MAXCOL is a big number.

The formatting attributes of a column are stored in ScColumn::pAttrArray ( type is ScAttrArray* )

The methods of ScAttrArray are mostly to set and get specific attributes in addition to
SetPattern(), SetPatternArea(), GetPattern() and GetPatternRange() which sets/gets whole set of formatting attributes for a row/row segment.

One of my ideas to solve the row formatting issue was to create and maintain a ScAttrArray object in ScTable (say aRowAttrArray) to hold only the row formattings.
In the ScTable *set* methods related to formatting we could check if the request is for the column range 0 to MAXCOL (full row operation) and
store the specified row formatting in aRowAttrArray in addition to letting the existing columns to receive the row formatting.

*For example* : 

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        for (SCCOL i = nStartCol; i <= nEndCol; i++)
            aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
    }
}

can be modified to :

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        
        if( nStartCol == 0 && nEndCol == MAXCOL )
        {
            aRowAttrArray.ApplyStyleArea(nStartRow, nEndRow, const_cast<ScStyleSheet*>(&rStyle));
            SCCOL nLastCol = aCol.size() - 1;
            for (SCCOL i = 0; i <= nLastCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);    
        }
        else
        {
            if ( aCol.size() <= nEndCol )
                aCol.CreateCol( nEndCol, nTab ); // This method has to be added again as the commit for loplugin:unusedmethods removed it.
            for (SCCOL i = nStartCol; i <= nEndCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
        }
    }
}

Now this aRowAttrArray can be used to instantiate pAttrArray of column to be created later on as it represents the attributes of all columns that are yet to be created.

Next we need to modify the Get methods of ScTable related to formatting in a way that it will respond with
correct formatting on the not-yet-created columns.

*For example* :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (ValidColRow(nCol,nRow))
         return aCol[nCol].GetPattern( nRow );
     else
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
}

needs to be modified to :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (!ValidColRow(nCol,nRow))
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
     if ( nCol < aCol.size() )
         return aCol[nCol].GetPattern( nRow );
     return aRowAttrArray.GetPattern( nRow );
}




While the above idea might work for a new document getting edited; but I am not sure what the situation is when a non trivial document is
loaded/saved. During file loading if row attributes get applied column by column separately, it will defeat the idea presented in the sample code above.
*For example*, a row stylesheet get applied by the import code by calling either :

1) for ( nCol = 0; nCol <= MAXCOL; ++nCol)
       ScTable::ApplyStyle(nCol, nRow, rStyle)
or

2) ScTable::ApplyStyleArea( 0, nRow, MAXCOL, nRow, rStyle )

In case 2) we can avoid creating all columns by special handling, but not in case 1)

In oox and excel import filters, it looks like attributes are applied column by column (more like case 1)
where it calls ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs& rAttrs ), which in-turn sets the Attr entries by directly manipulating pAttrArray of each column.
In oox and excel formats, I am not sure if there is a way to store row attributes.

For ods doc, I could not find direct evidence on how row attributes are applied, but I found out that ods has a way to store row attributes by examining the content.xml of an ods file with a row formatting, so
the import code would definitely have a chance to call the Set*Area() or Set*Range() or ApplyStyleArea() directly rather than setting attributes for each column in a loop for the row attributes.


It would be great if someone could comment on the approach and offer some advice on my import code doubts presented above.



Thanks a lot,
Dennis

On Wed, Jan 20, 2016 at 1:34 PM, Dennis Francis <[hidden email]> wrote:
Hi All

I have submitted a prelim patch at https://gerrit.libreoffice.org/21620 following Kohei's suggestion of
solving this bug incrementally.

Thanks,
Dennis

On Wed, Oct 14, 2015 at 10:22 PM, Kohei Yoshida <[hidden email]> wrote:


> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice



_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Adding Markus and Eike to make sure they did not miss my last post in this thread.

Thanks in advance for your feedback.

Thanks,
Dennis


On Fri, Jun 10, 2016 at 3:08 PM, Dennis Francis <[hidden email]> wrote:
Hi All

It has been quite a while since I worked on this bug. Lately I have been thinking about "a better way to handle row formattings".
In the current setting, if someone formats whole row, it is required that we have all columns from 0 to MAXCOL allocated, which is bad when MAXCOL is a big number.

The formatting attributes of a column are stored in ScColumn::pAttrArray ( type is ScAttrArray* )

The methods of ScAttrArray are mostly to set and get specific attributes in addition to
SetPattern(), SetPatternArea(), GetPattern() and GetPatternRange() which sets/gets whole set of formatting attributes for a row/row segment.

One of my ideas to solve the row formatting issue was to create and maintain a ScAttrArray object in ScTable (say aRowAttrArray) to hold only the row formattings.
In the ScTable *set* methods related to formatting we could check if the request is for the column range 0 to MAXCOL (full row operation) and
store the specified row formatting in aRowAttrArray in addition to letting the existing columns to receive the row formatting.

*For example* : 

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        for (SCCOL i = nStartCol; i <= nEndCol; i++)
            aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
    }
}

can be modified to :

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        
        if( nStartCol == 0 && nEndCol == MAXCOL )
        {
            aRowAttrArray.ApplyStyleArea(nStartRow, nEndRow, const_cast<ScStyleSheet*>(&rStyle));
            SCCOL nLastCol = aCol.size() - 1;
            for (SCCOL i = 0; i <= nLastCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);    
        }
        else
        {
            if ( aCol.size() <= nEndCol )
                aCol.CreateCol( nEndCol, nTab ); // This method has to be added again as the commit for loplugin:unusedmethods removed it.
            for (SCCOL i = nStartCol; i <= nEndCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
        }
    }
}

Now this aRowAttrArray can be used to instantiate pAttrArray of column to be created later on as it represents the attributes of all columns that are yet to be created.

Next we need to modify the Get methods of ScTable related to formatting in a way that it will respond with
correct formatting on the not-yet-created columns.

*For example* :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (ValidColRow(nCol,nRow))
         return aCol[nCol].GetPattern( nRow );
     else
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
}

needs to be modified to :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (!ValidColRow(nCol,nRow))
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
     if ( nCol < aCol.size() )
         return aCol[nCol].GetPattern( nRow );
     return aRowAttrArray.GetPattern( nRow );
}




While the above idea might work for a new document getting edited; but I am not sure what the situation is when a non trivial document is
loaded/saved. During file loading if row attributes get applied column by column separately, it will defeat the idea presented in the sample code above.
*For example*, a row stylesheet get applied by the import code by calling either :

1) for ( nCol = 0; nCol <= MAXCOL; ++nCol)
       ScTable::ApplyStyle(nCol, nRow, rStyle)
or

2) ScTable::ApplyStyleArea( 0, nRow, MAXCOL, nRow, rStyle )

In case 2) we can avoid creating all columns by special handling, but not in case 1)

In oox and excel import filters, it looks like attributes are applied column by column (more like case 1)
where it calls ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs& rAttrs ), which in-turn sets the Attr entries by directly manipulating pAttrArray of each column.
In oox and excel formats, I am not sure if there is a way to store row attributes.

For ods doc, I could not find direct evidence on how row attributes are applied, but I found out that ods has a way to store row attributes by examining the content.xml of an ods file with a row formatting, so
the import code would definitely have a chance to call the Set*Area() or Set*Range() or ApplyStyleArea() directly rather than setting attributes for each column in a loop for the row attributes.


It would be great if someone could comment on the approach and offer some advice on my import code doubts presented above.



Thanks a lot,
Dennis

On Wed, Jan 20, 2016 at 1:34 PM, Dennis Francis <[hidden email]> wrote:
Hi All

I have submitted a prelim patch at https://gerrit.libreoffice.org/21620 following Kohei's suggestion of
solving this bug incrementally.

Thanks,
Dennis

On Wed, Oct 14, 2015 at 10:22 PM, Kohei Yoshida <[hidden email]> wrote:


> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice




_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi All

I have compiled a writeup @ https://niocs.github.io/LOBook/misc/16kcols.html to help new contributors who want to work on this bug tdf#50916.
I will try to keep it updated on new developments as more patches are added.

Thanks,
Dennis


On Mon, Jun 20, 2016 at 3:40 PM, Dennis Francis <[hidden email]> wrote:
Adding Markus and Eike to make sure they did not miss my last post in this thread.

Thanks in advance for your feedback.

Thanks,
Dennis


On Fri, Jun 10, 2016 at 3:08 PM, Dennis Francis <[hidden email]> wrote:
Hi All

It has been quite a while since I worked on this bug. Lately I have been thinking about "a better way to handle row formattings".
In the current setting, if someone formats whole row, it is required that we have all columns from 0 to MAXCOL allocated, which is bad when MAXCOL is a big number.

The formatting attributes of a column are stored in ScColumn::pAttrArray ( type is ScAttrArray* )

The methods of ScAttrArray are mostly to set and get specific attributes in addition to
SetPattern(), SetPatternArea(), GetPattern() and GetPatternRange() which sets/gets whole set of formatting attributes for a row/row segment.

One of my ideas to solve the row formatting issue was to create and maintain a ScAttrArray object in ScTable (say aRowAttrArray) to hold only the row formattings.
In the ScTable *set* methods related to formatting we could check if the request is for the column range 0 to MAXCOL (full row operation) and
store the specified row formatting in aRowAttrArray in addition to letting the existing columns to receive the row formatting.

*For example* : 

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        for (SCCOL i = nStartCol; i <= nEndCol; i++)
            aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
    }
}

can be modified to :

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        
        if( nStartCol == 0 && nEndCol == MAXCOL )
        {
            aRowAttrArray.ApplyStyleArea(nStartRow, nEndRow, const_cast<ScStyleSheet*>(&rStyle));
            SCCOL nLastCol = aCol.size() - 1;
            for (SCCOL i = 0; i <= nLastCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);    
        }
        else
        {
            if ( aCol.size() <= nEndCol )
                aCol.CreateCol( nEndCol, nTab ); // This method has to be added again as the commit for loplugin:unusedmethods removed it.
            for (SCCOL i = nStartCol; i <= nEndCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
        }
    }
}

Now this aRowAttrArray can be used to instantiate pAttrArray of column to be created later on as it represents the attributes of all columns that are yet to be created.

Next we need to modify the Get methods of ScTable related to formatting in a way that it will respond with
correct formatting on the not-yet-created columns.

*For example* :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (ValidColRow(nCol,nRow))
         return aCol[nCol].GetPattern( nRow );
     else
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
}

needs to be modified to :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (!ValidColRow(nCol,nRow))
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
     if ( nCol < aCol.size() )
         return aCol[nCol].GetPattern( nRow );
     return aRowAttrArray.GetPattern( nRow );
}




While the above idea might work for a new document getting edited; but I am not sure what the situation is when a non trivial document is
loaded/saved. During file loading if row attributes get applied column by column separately, it will defeat the idea presented in the sample code above.
*For example*, a row stylesheet get applied by the import code by calling either :

1) for ( nCol = 0; nCol <= MAXCOL; ++nCol)
       ScTable::ApplyStyle(nCol, nRow, rStyle)
or

2) ScTable::ApplyStyleArea( 0, nRow, MAXCOL, nRow, rStyle )

In case 2) we can avoid creating all columns by special handling, but not in case 1)

In oox and excel import filters, it looks like attributes are applied column by column (more like case 1)
where it calls ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs& rAttrs ), which in-turn sets the Attr entries by directly manipulating pAttrArray of each column.
In oox and excel formats, I am not sure if there is a way to store row attributes.

For ods doc, I could not find direct evidence on how row attributes are applied, but I found out that ods has a way to store row attributes by examining the content.xml of an ods file with a row formatting, so
the import code would definitely have a chance to call the Set*Area() or Set*Range() or ApplyStyleArea() directly rather than setting attributes for each column in a loop for the row attributes.


It would be great if someone could comment on the approach and offer some advice on my import code doubts presented above.



Thanks a lot,
Dennis

On Wed, Jan 20, 2016 at 1:34 PM, Dennis Francis <[hidden email]> wrote:
Hi All

I have submitted a prelim patch at https://gerrit.libreoffice.org/21620 following Kohei's suggestion of
solving this bug incrementally.

Thanks,
Dennis

On Wed, Oct 14, 2015 at 10:22 PM, Kohei Yoshida <[hidden email]> wrote:


> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice





_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
marius adrian popa marius adrian popa
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container


On Mon, Feb 6, 2017 at 2:27 PM, Dennis Francis <[hidden email]> wrote:
Hi All

I have compiled a writeup @ https://niocs.github.io/LOBook/misc/16kcols.html to help new contributors who want to work on this bug tdf#50916.
I will try to keep it updated on new developments as more patches are added.

Thanks,
Dennis


On Mon, Jun 20, 2016 at 3:40 PM, Dennis Francis <[hidden email]> wrote:
Adding Markus and Eike to make sure they did not miss my last post in this thread.

Thanks in advance for your feedback.

Thanks,
Dennis


On Fri, Jun 10, 2016 at 3:08 PM, Dennis Francis <[hidden email]> wrote:
Hi All

It has been quite a while since I worked on this bug. Lately I have been thinking about "a better way to handle row formattings".
In the current setting, if someone formats whole row, it is required that we have all columns from 0 to MAXCOL allocated, which is bad when MAXCOL is a big number.

The formatting attributes of a column are stored in ScColumn::pAttrArray ( type is ScAttrArray* )

The methods of ScAttrArray are mostly to set and get specific attributes in addition to
SetPattern(), SetPatternArea(), GetPattern() and GetPatternRange() which sets/gets whole set of formatting attributes for a row/row segment.

One of my ideas to solve the row formatting issue was to create and maintain a ScAttrArray object in ScTable (say aRowAttrArray) to hold only the row formattings.
In the ScTable *set* methods related to formatting we could check if the request is for the column range 0 to MAXCOL (full row operation) and
store the specified row formatting in aRowAttrArray in addition to letting the existing columns to receive the row formatting.

*For example* : 

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        for (SCCOL i = nStartCol; i <= nEndCol; i++)
            aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
    }
}

can be modified to :

void ScTable::ApplyStyleArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScStyleSheet& rStyle )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        
        if( nStartCol == 0 && nEndCol == MAXCOL )
        {
            aRowAttrArray.ApplyStyleArea(nStartRow, nEndRow, const_cast<ScStyleSheet*>(&rStyle));
            SCCOL nLastCol = aCol.size() - 1;
            for (SCCOL i = 0; i <= nLastCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);    
        }
        else
        {
            if ( aCol.size() <= nEndCol )
                aCol.CreateCol( nEndCol, nTab ); // This method has to be added again as the commit for loplugin:unusedmethods removed it.
            for (SCCOL i = nStartCol; i <= nEndCol; i++)
                aCol[i].ApplyStyleArea(nStartRow, nEndRow, rStyle);
        }
    }
}

Now this aRowAttrArray can be used to instantiate pAttrArray of column to be created later on as it represents the attributes of all columns that are yet to be created.

Next we need to modify the Get methods of ScTable related to formatting in a way that it will respond with
correct formatting on the not-yet-created columns.

*For example* :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (ValidColRow(nCol,nRow))
         return aCol[nCol].GetPattern( nRow );
     else
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
}

needs to be modified to :

const ScPatternAttr* ScTable::GetPattern( SCCOL nCol, SCROW nRow ) const
{
     if (!ValidColRow(nCol,nRow))
     {
         OSL_FAIL("wrong column or row");
         return pDocument->GetDefPattern();      // for safety
     }
     if ( nCol < aCol.size() )
         return aCol[nCol].GetPattern( nRow );
     return aRowAttrArray.GetPattern( nRow );
}




While the above idea might work for a new document getting edited; but I am not sure what the situation is when a non trivial document is
loaded/saved. During file loading if row attributes get applied column by column separately, it will defeat the idea presented in the sample code above.
*For example*, a row stylesheet get applied by the import code by calling either :

1) for ( nCol = 0; nCol <= MAXCOL; ++nCol)
       ScTable::ApplyStyle(nCol, nRow, rStyle)
or

2) ScTable::ApplyStyleArea( 0, nRow, MAXCOL, nRow, rStyle )

In case 2) we can avoid creating all columns by special handling, but not in case 1)

In oox and excel import filters, it looks like attributes are applied column by column (more like case 1)
where it calls ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs& rAttrs ), which in-turn sets the Attr entries by directly manipulating pAttrArray of each column.
In oox and excel formats, I am not sure if there is a way to store row attributes.

For ods doc, I could not find direct evidence on how row attributes are applied, but I found out that ods has a way to store row attributes by examining the content.xml of an ods file with a row formatting, so
the import code would definitely have a chance to call the Set*Area() or Set*Range() or ApplyStyleArea() directly rather than setting attributes for each column in a loop for the row attributes.


It would be great if someone could comment on the approach and offer some advice on my import code doubts presented above.



Thanks a lot,
Dennis

On Wed, Jan 20, 2016 at 1:34 PM, Dennis Francis <[hidden email]> wrote:
Hi All

I have submitted a prelim patch at https://gerrit.libreoffice.org/21620 following Kohei's suggestion of
solving this bug incrementally.

Thanks,
Dennis

On Wed, Oct 14, 2015 at 10:22 PM, Kohei Yoshida <[hidden email]> wrote:


> On October 14, 2015 at 11:18 AM Wols Lists <[hidden email]> wrote:
>
>
> On 14/10/15 02:08, Kohei Yoshida wrote:
> > Also, this will be an on-going process.  This is not going to be like
> > "if you do A, B and C it's okay to increase the column size and no
> > problems will occur".  Rather, we'll probably encounter lots of
> > performance issues that we'll have to spend some time fixing after the
> > column size is increased.
>
> Just throwing an idea into the mix...
>
> Howsabout a function that, on being given the cell co-ordinates, returns
> a pointer to the cell. Force everything through that.

Its internal representation is no longer cell-based. So, there would be no
"pointer to cell" to return.
_______________________________________________
LibreOffice mailing list
[hidden email]
http://lists.freedesktop.org/mailman/listinfo/libreoffice





_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice



_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
Eike Rathke-2 Eike Rathke-2
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

In reply to this post by Dennis Francis
Hi Dennis,

On Monday, 2017-02-06 17:57:32 +0530, Dennis Francis wrote:

> I have compiled a writeup @ https://niocs.github.io/LOBook/misc/16kcols.html to
> help new contributors who want to work on this bug tdf#50916.
> I will try to keep it updated on new developments as more patches are added.

Thanks, but wouldn't the right place for that be our wiki instead?

  Eike

--
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key "ID" 0x65632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Better use 64-bit 0x6A6CD5B765632D3A here is why: https://evil32.com/
Care about Free Software, support the FSFE https://fsfe.org/support/?erack

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

signature.asc (836 bytes) Download Attachment
Dennis Francis Dennis Francis
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi Eike

On Thu, Feb 16, 2017 at 10:12 PM, Eike Rathke <[hidden email]> wrote:
Hi Dennis,

Thanks, but wouldn't the right place for that be our wiki instead?


Thanks,
Dennis

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice
Eike Rathke-2 Eike Rathke-2
Reply | Threaded
Open this post in threaded view
|

Re: tdf#50916 : Calc : Dynamic column container

Hi Dennis,

On Wednesday, 2017-06-07 20:11:38 +0530, Dennis Francis wrote:

> I have added the content at
> https://wiki.documentfoundation.org/Development/Calc#Increasing_the_limit_of_number_of_columns_from_1024_to_16384
> <https://wiki.documentfoundation.org/Development/Calc#Increasing_the_limit_of_number_of_columns_from_1024_to_16384>

Muchas gracias!

  Eike

--
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key 0x6A6CD5B765632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Care about Free Software, support the FSFE https://fsfe.org/support/?erack

_______________________________________________
LibreOffice mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

signature.asc (836 bytes) Download Attachment