kspread

kspread_dlg_format.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002-2003 Norbert Andres <nandres@web.de>
3 (C) 2002 Ariya Hidayat <ariya@kde.org>
4 (C) 2002 John Dailey <dailey@vt.edu>
5 (C) 2001-2002 Philipp Mueller <philipp.mueller@gmx.de>
6 (C) 2000-2002 Laurent Montel <montel@kde.org>
7 (C) 2000 Werner Trobin <trobin@kde.org>
8 (C) 1998-2000 Torben Weis <weis@kde.org>
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24*/
25
26#include <tqcombobox.h>
27#include <tqfile.h>
28#include <tqlayout.h>
29#include <tqlabel.h>
30#include <tqpushbutton.h>
31
32#include <kbuttonbox.h>
33#include <tdemessagebox.h>
34#include <kstandarddirs.h>
35#include <ksimpleconfig.h>
36
37#include "kspread_dlg_format.h"
38#include "kspread_doc.h"
39#include "kspread_locale.h"
40#include "kspread_sheet.h"
41#include "kspread_style.h"
42#include "kspread_style_manager.h"
43#include "kspread_undo.h"
44#include "kspread_view.h"
45#include "selection.h"
46
47
48using namespace KSpread;
49
50FormatDialog::FormatDialog( View* view, const char* name )
51 : KDialogBase( view, name, true,i18n("Sheet Style"),Ok|Cancel )
52{
53 for( int i = 0; i < 16; ++i )
54 m_cells[ i ] = 0;
55
56 m_view = view;
57 TQWidget *page = new TQWidget( this );
58 setMainWidget(page);
59 TQVBoxLayout *vbox = new TQVBoxLayout( page, 0, spacingHint() );
60
61 TQLabel *toplabel = new TQLabel( i18n("Select the sheet style to apply:"), page );
62 m_combo = new TQComboBox( page );
63 m_label = new TQLabel( page );
64
65 vbox->addWidget( toplabel );
66 vbox->addWidget( m_combo );
67 vbox->addWidget( m_label );
68
69
70 TQStringList lst = Factory::global()->dirs()->findAllResources( "sheet-styles", "*.ksts", true );
71
72 TQStringList::Iterator it = lst.begin();
73 for( ; it != lst.end(); ++it )
74 {
75 KSimpleConfig cfg( *it, true );
76 cfg.setGroup( "Sheet-Style" );
77
78 Entry e;
79 e.config = *it;
80 e.xml = cfg.readEntry( "XML" );
81 e.image = cfg.readEntry( "Image" );
82 e.name = cfg.readEntry( "Name" );
83
84 m_entries.append( e );
85
86 m_combo->insertItem( e.name );
87 }
88
89 slotActivated( 0 );
90
91 connect( this, TQ_SIGNAL( okClicked() ), this, TQ_SLOT( slotOk() ) );
92 connect( m_combo, TQ_SIGNAL( activated( int ) ), this, TQ_SLOT( slotActivated( int ) ) );
93}
94
95FormatDialog::~FormatDialog()
96{
97 for( int i = 0; i < 16; ++i )
98 delete m_cells[ i ];
99}
100
101void FormatDialog::slotActivated( int index )
102{
103 enableButtonOK(true);
104
105 TQString img = Factory::global()->dirs()->findResource( "sheet-styles", m_entries[ index ].image );
106 if ( img.isEmpty() )
107 {
108 TQString str( i18n( "Could not find image %1." ) );
109 str = str.arg( m_entries[ index ].image );
110 KMessageBox::error( this, str );
111
112 enableButtonOK(false);
113
114 return;
115 }
116
117 TQPixmap pix( img );
118 if ( pix.isNull() )
119 {
120 TQString str( i18n( "Could not load image %1." ) );
121 str = str.arg( img );
122 KMessageBox::error( this,str );
123
124 enableButtonOK(false);
125
126 return;
127 }
128
129 m_label->setPixmap( pix );
130}
131
132void FormatDialog::slotOk()
133{
134
135 m_view->doc()->emitBeginOperation( false );
136
137 TQString xml = Factory::global()->dirs()->findResource( "sheet-styles", m_entries[ m_combo->currentItem() ].xml );
138 if ( xml.isEmpty() )
139 {
140 TQString str( i18n( "Could not find sheet-style XML file '%1'." ) );
141 str = str.arg( m_entries[ m_combo->currentItem() ].xml );
142 KMessageBox::error( this, str );
143 return;
144 }
145
146 TQFile file( xml );
147 file.open( IO_ReadOnly );
148 TQDomDocument doc;
149 doc.setContent( &file );
150 file.close();
151
152 if ( !parseXML( doc ) )
153 {
154 TQString str( i18n( "Parsing error in sheet-style XML file %1." ) );
155 str = str.arg( m_entries[ m_combo->currentItem() ].xml );
156 KMessageBox::error( this, str );
157 return;
158 }
159
160 TQRect r = m_view->selectionInfo()->selection();
161
162 if ( !m_view->doc()->undoLocked() )
163 {
164 TQString title=i18n("Change Format");
165 UndoCellFormat *undo = new UndoCellFormat( m_view->doc(), m_view->activeSheet(), r, title);
166 m_view->doc()->addCommand( undo );
167 }
168 //
169 // Set colors, borders etc.
170 //
171
172 // Top left corner
173 Cell* cell = m_view->activeSheet()->nonDefaultCell( r.left(), r.top() );
174 cell->format()->copy( *m_cells[0] );
175
176 // Top column
177 int x, y;
178 for( x = r.left() + 1; x <= r.right(); ++x )
179 {
180 int pos = 1 + ( ( x - r.left() - 1 ) % 2 );
181 Cell* cell = m_view->activeSheet()->nonDefaultCell( x, r.top() );
182 if(!cell->isPartOfMerged())
183 {
184 cell->format()->copy( *m_cells[ pos ] );
185
186 Format* c;
187 if ( x == r.right() )
188 c = m_cells[2];
189 else
190 c = m_cells[1];
191
192 if ( c )
193 cell->setTopBorderPen( c->topBorderPen( 0, 0 ) );
194
195 if ( x == r.left() + 1 )
196 c = m_cells[1];
197 else
198 c = m_cells[2];
199
200 if ( c )
201 cell->setLeftBorderPen( c->leftBorderPen( 0, 0 ) );
202 }
203 }
204
205 cell = m_view->activeSheet()->nonDefaultCell( r.right(), r.top() );
206 if ( m_cells[3] )
207 cell->setRightBorderPen( m_cells[3]->leftBorderPen( 0, 0 ) );
208
209 // Left row
210 for( y = r.top() + 1; y <= r.bottom(); ++y )
211 {
212 int pos = 4 + ( ( y - r.top() - 1 ) % 2 ) * 4;
213 Cell* cell = m_view->activeSheet()->nonDefaultCell( r.left(), y );
214 if(!cell->isPartOfMerged())
215 {
216 cell->format()->copy( *m_cells[ pos ] );
217
218 Format* c;
219 if ( y == r.bottom() )
220 c = m_cells[8];
221 else
222 c = m_cells[4];
223
224 if ( c )
225 cell->setLeftBorderPen( c->leftBorderPen( 0, 0 ) );
226
227 if ( y == r.top() + 1 )
228 c = m_cells[4];
229 else
230 c = m_cells[8];
231
232 if ( c )
233 cell->setTopBorderPen( c->topBorderPen( 0, 0 ) );
234 }
235 }
236
237 // Body
238 for( x = r.left() + 1; x <= r.right(); ++x )
239 for( y = r.top() + 1; y <= r.bottom(); ++y )
240 {
241 int pos = 5 + ( ( y - r.top() - 1 ) % 2 ) * 4 + ( ( x - r.left() - 1 ) % 2 );
242 Cell* cell = m_view->activeSheet()->nonDefaultCell( x, y );
243 if(!cell->isPartOfMerged())
244 {
245 cell->format()->copy( *m_cells[ pos ] );
246
247 Format* c;
248 if ( x == r.left() + 1 )
249 c = m_cells[ 5 + ( ( y - r.top() - 1 ) % 2 ) * 4 ];
250 else
251 c = m_cells[ 6 + ( ( y - r.top() - 1 ) % 2 ) * 4 ];
252
253 if ( c )
254 cell->setLeftBorderPen( c->leftBorderPen( 0, 0 ) );
255
256 if ( y == r.top() + 1 )
257 c = m_cells[ 5 + ( ( x - r.left() - 1 ) % 2 ) ];
258 else
259 c = m_cells[ 9 + ( ( x - r.left() - 1 ) % 2 ) ];
260
261 if ( c )
262 cell->setTopBorderPen( c->topBorderPen( 0, 0 ) );
263 }
264 }
265
266 // Outer right border
267 for( y = r.top(); y <= r.bottom(); ++y )
268 {
269 Cell* cell = m_view->activeSheet()->nonDefaultCell( r.right(), y );
270 if(!cell->isPartOfMerged())
271 {
272 if ( y == r.top() )
273 {
274 if ( m_cells[3] )
275 cell->setRightBorderPen( m_cells[3]->leftBorderPen( 0, 0 ) );
276 }
277 else if ( y == r.right() )
278 {
279 if ( m_cells[11] )
280 cell->setRightBorderPen( m_cells[11]->leftBorderPen( 0, 0 ) );
281 }
282 else
283 {
284 if ( m_cells[7] )
285 cell->setRightBorderPen( m_cells[7]->leftBorderPen( 0, 0 ) );
286 }
287 }
288 }
289
290 // Outer bottom border
291 for( x = r.left(); x <= r.right(); ++x )
292 {
293 Cell* cell = m_view->activeSheet()->nonDefaultCell( x, r.bottom() );
294 if(!cell->isPartOfMerged())
295 {
296 if ( x == r.left() )
297 {
298 if ( m_cells[12] )
299 cell->setBottomBorderPen( m_cells[12]->topBorderPen( 0, 0 ) );
300 }
301 else if ( x == r.right() )
302 {
303 if ( m_cells[14] )
304 cell->setBottomBorderPen( m_cells[14]->topBorderPen( 0, 0 ) );
305 }
306 else
307 {
308 if ( m_cells[13] )
309 cell->setBottomBorderPen( m_cells[13]->topBorderPen( 0, 0 ) );
310 }
311 }
312 }
313
314 m_view->selectionInfo()->initialize(r);//, m_view->activeSheet() );
315 m_view->doc()->setModified( true );
316 m_view->slotUpdateView( m_view->activeSheet() );
317 accept();
318}
319
320bool FormatDialog::parseXML( const TQDomDocument& doc )
321{
322 for( int i = 0; i < 16; ++i )
323 {
324 delete m_cells[ i ];
325 m_cells[ i ] = 0;
326 }
327
328 TQDomElement e = doc.documentElement().firstChild().toElement();
329 for( ; !e.isNull(); e = e.nextSibling().toElement() )
330 {
331 if ( e.tagName() == "cell" )
332 {
333 Sheet* sheet = m_view->activeSheet();
334 Format* cell = new Format( sheet, sheet->doc()->styleManager()->defaultStyle() );
335
336 if ( !cell->load( e.namedItem("format").toElement(), Paste::Normal ) )
337 return false;
338
339 int row = e.attribute("row").toInt();
340 int column = e.attribute("column").toInt();
341 int i = (row-1)*4 + (column-1);
342 if ( i < 0 || i >= 16 )
343 return false;
344
345 m_cells[ i ] = cell;
346 }
347 }
348
349 return true;
350}
351
352#include "kspread_dlg_format.moc"
For every cell in the spread sheet there is a Cell object.
void setRightBorderPen(const TQPen &p)
void setTopBorderPen(const TQPen &p)
Format * format() const
Returns the format object of this cell.
void setBottomBorderPen(const TQPen &p)
bool isPartOfMerged() const
If this cell is part of a merged cell, then the marker may never reside on this cell.
void setLeftBorderPen(const TQPen &p)
bool undoLocked() const
Returns true if undo buffer is locked.
void emitBeginOperation(bool waitCursor)
Functions to begin a kspread 'operation'.
void addCommand(KCommand *command)
Adds a command to the command history.
The View class displays a KSpread document.
@ Format
Format only.
@ Normal
Everything.
The KSpread namespace.
Definition commands.h:39