forked from ScoDoc/ScoDoc
231 lines
8.1 KiB
Python
Executable File
231 lines
8.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: windows-1251 -*-
|
|
|
|
# Copyright (C) 2005 Roman V. Kiseliov
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
#
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in
|
|
# the documentation and/or other materials provided with the
|
|
# distribution.
|
|
#
|
|
# 3. All advertising materials mentioning features or use of this
|
|
# software must display the following acknowledgment:
|
|
# "This product includes software developed by
|
|
# Roman V. Kiseliov <roman@kiseliov.ru>."
|
|
#
|
|
# 4. Redistributions of any form whatsoever must retain the following
|
|
# acknowledgment:
|
|
# "This product includes software developed by
|
|
# Roman V. Kiseliov <roman@kiseliov.ru>."
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY Roman V. Kiseliov ``AS IS'' AND ANY
|
|
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Roman V. Kiseliov OR
|
|
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
__rev_id__ = """$Id: Row.py,v 1.6 2005/08/11 08:53:48 rvk Exp $"""
|
|
|
|
|
|
import BIFFRecords
|
|
from Deco import *
|
|
from Worksheet import Worksheet
|
|
import Style
|
|
import Cell
|
|
import ExcelFormula
|
|
import datetime as dt
|
|
|
|
|
|
class Row(object):
|
|
__slots__ = ["__init__",
|
|
"__adjust_height",
|
|
"__adjust_bound_col_idx",
|
|
"__excel_date_dt",
|
|
"get_height_in_pixels",
|
|
"set_style",
|
|
"get_xf_index",
|
|
"get_cells_count",
|
|
"get_min_col",
|
|
"get_max_col",
|
|
"get_str_count",
|
|
"get_row_biff_data",
|
|
"get_cells_biff_data",
|
|
"get_index",
|
|
"write",
|
|
"write_blanks",
|
|
# private variables
|
|
"__idx",
|
|
"__parent",
|
|
"__parent_wb",
|
|
"__cells",
|
|
"__min_col_idx",
|
|
"__max_col_idx",
|
|
"__total_str",
|
|
"__xf_index",
|
|
"__has_default_format",
|
|
"__height_in_pixels",
|
|
# public variables
|
|
"height",
|
|
"has_default_height",
|
|
"level",
|
|
"collapse",
|
|
"hidden",
|
|
"space_above",
|
|
"space_below"]
|
|
|
|
#################################################################
|
|
## Constructor
|
|
#################################################################
|
|
def __init__(self, index, parent_sheet):
|
|
self.__idx = index
|
|
self.__parent = parent_sheet
|
|
self.__parent_wb = parent_sheet.get_parent()
|
|
self.__cells = []
|
|
self.__min_col_idx = 0
|
|
self.__max_col_idx = 0
|
|
self.__total_str = 0
|
|
self.__xf_index = 0x0F
|
|
self.__has_default_format = 0
|
|
self.__height_in_pixels = 0x11
|
|
|
|
self.height = 0x00FF
|
|
self.has_default_height = 0x00
|
|
self.level = 0
|
|
self.collapse = 0
|
|
self.hidden = 0
|
|
self.space_above = 0
|
|
self.space_below = 0
|
|
|
|
|
|
def __adjust_height(self, style):
|
|
twips = style.font.height
|
|
points = float(twips)/20.0
|
|
# Cell height in pixels can be calcuted by following approx. formula:
|
|
# cell height in pixels = font height in points * 83/50 + 2/5
|
|
# It works when screen resolution is 96 dpi
|
|
pix = int(round(points*83.0/50.0 + 2.0/5.0))
|
|
if pix > self.__height_in_pixels:
|
|
self.__height_in_pixels = pix
|
|
|
|
|
|
def __adjust_bound_col_idx(self, *args):
|
|
for arg in args:
|
|
if arg < self.__min_col_idx:
|
|
self.__min_col_idx = arg
|
|
elif arg > self.__max_col_idx:
|
|
self.__max_col_idx = arg
|
|
|
|
def __excel_date_dt(self, date):
|
|
if isinstance(date, dt.date) and (not isinstance(date, dt.datetime)):
|
|
epoch = dt.date(1899, 12, 31)
|
|
elif isinstance(date, dt.time):
|
|
date = dt.datetime.combine(dt.datetime(1900, 1, 1), date)
|
|
epoch = dt.datetime(1900, 1, 1, 0, 0, 0)
|
|
else:
|
|
epoch = dt.datetime(1899, 12, 31, 0, 0, 0)
|
|
delta = date - epoch
|
|
xldate = delta.days + float(delta.seconds) / (24*60*60)
|
|
# Add a day for Excel's missing leap day in 1900
|
|
if xldate > 59:
|
|
xldate += 1
|
|
return xldate
|
|
|
|
def get_height_in_pixels(self):
|
|
return self.__height_in_pixels
|
|
|
|
|
|
#accepts(object, Style.XFStyle)
|
|
def set_style(self, style):
|
|
self.__adjust_height(style)
|
|
self.__xf_index = self.__parent_wb.add_style(style)
|
|
|
|
|
|
def get_xf_index(self):
|
|
return self.__xf_index
|
|
|
|
|
|
def get_cells_count(self):
|
|
return len(self.__cells)
|
|
|
|
|
|
def get_min_col(self):
|
|
return self.__min_col_idx
|
|
|
|
|
|
def get_max_col(self):
|
|
return self.__min_col_idx
|
|
|
|
|
|
def get_str_count(self):
|
|
return self.__total_str
|
|
|
|
|
|
def get_row_biff_data(self):
|
|
height_options = (self.height & 0x07FFF)
|
|
height_options |= (self.has_default_height & 0x01) << 15
|
|
|
|
options = (self.level & 0x07) << 0
|
|
options |= (self.collapse & 0x01) << 4
|
|
options |= (self.hidden & 0x01) << 5
|
|
options |= (0x00 & 0x01) << 6
|
|
options |= (0x01 & 0x01) << 8
|
|
if self.__xf_index != 0x0F:
|
|
options |= (0x01 & 0x01) << 7
|
|
else:
|
|
options |= (0x00 & 0x01) << 7
|
|
options |= (self.__xf_index & 0x0FFF) << 16
|
|
options |= (0x00 & self.space_above) << 28
|
|
options |= (0x00 & self.space_below) << 29
|
|
|
|
return BIFFRecords.RowRecord(self.__idx, self.__min_col_idx, self.__max_col_idx, height_options, options).get()
|
|
|
|
|
|
def get_cells_biff_data(self):
|
|
return ''.join([ cell.get_biff_data() for cell in self.__cells ])
|
|
|
|
|
|
def get_index(self):
|
|
return self.__idx
|
|
|
|
|
|
#accepts(object, int, (str, unicode, int, float, dt.datetime, dt.time, dt.date, ExcelFormula.Formula), Style.XFStyle)
|
|
def write(self, col, label, style):
|
|
self.__adjust_height(style)
|
|
self.__adjust_bound_col_idx(col)
|
|
if isinstance(label, (str, unicode)):
|
|
if len(label) > 0:
|
|
self.__cells.extend([ Cell.StrCell(self, col, self.__parent_wb.add_style(style), self.__parent_wb.add_str(label)) ])
|
|
self.__total_str += 1
|
|
else:
|
|
self.__cells.extend([ Cell.BlankCell(self, col, self.__parent_wb.add_style(style)) ])
|
|
elif isinstance(label, (int, float)):
|
|
self.__cells.extend([ Cell.NumberCell(self, col, self.__parent_wb.add_style(style), label) ])
|
|
elif isinstance(label, (dt.datetime, dt.time)):
|
|
self.__cells.extend([ Cell.NumberCell(self, col, self.__parent_wb.add_style(style), self.__excel_date_dt(label)) ])
|
|
else:
|
|
self.__cells.extend([ Cell.FormulaCell(self, col, self.__parent_wb.add_style(style), label) ])
|
|
|
|
#accepts(object, int, int, Style.XFStyle)
|
|
def write_blanks(self, c1, c2, style):
|
|
self.__adjust_height(style)
|
|
self.__adjust_bound_col_idx(c1, c2)
|
|
self.__cells.extend([ Cell.MulBlankCell(self, c1, c2, self.__parent_wb.add_style(style)) ])
|
|
|
|
|
|
|