kspread

kspread_plugininsertcalendar.cpp
1/***************************************************************************
2 * Copyright (C) 2005 by Raphael Langerhorst *
3 * raphael-langerhorst@gmx.at *
4 * *
5 * Permission is hereby granted, free of charge, to any person obtaining *
6 * a copy of this software and associated documentation files (the *
7 * "Software"), to deal in the Software without restriction, including *
8 * without limitation the rights to use, copy, modify, merge, publish, *
9 * distribute, sublicense, and/or sell copies of the Software, and to *
10 * permit persons to whom the Software is furnished to do so, subject to *
11 * the following conditions: *
12 * *
13 * The above copyright notice and this permission notice shall be *
14 * included in all copies or substantial portions of the Software. *
15 * *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
22 * OTHER DEALINGS IN THE SOFTWARE. *
23 ***************************************************************************/
24
25#include "kspread_plugininsertcalendar.h"
26
27#include "kspread_insertcalendardialog.h"
28
29#include "../../kspread_view.h"
30#include "../../kspread_doc.h"
31#include "../../selection.h"
32#include "../../kspread_sheet.h"
33
34#include <kcalendarsystem.h>
35#include <kcalendarsystemfactory.h>
36#include <tdeaboutdata.h>
37#include <kgenericfactory.h>
38#include <tdelocale.h>
39#include <kofficeversion.h>
40#include <tdemessagebox.h>
41
42#include <tqpoint.h>
43#include <tqrect.h>
44
45namespace KSpread
46{
47
48// make the plugin available
49typedef KGenericFactory<PluginInsertCalendar> InsertCalendarFactory;
50K_EXPORT_COMPONENT_FACTORY( libkspreadinsertcalendar, InsertCalendarFactory("kspreadinsertcalendar"))
51
52
53PluginInsertCalendar::PluginInsertCalendar( TQObject *parent, const char *name, const TQStringList& /*args*/ )
54: Plugin(parent,name)
55{
56 this->m_kspreadView = NULL;
57 if (parent)
58 {
59 if (parent->inherits("KSpread::View"))
60 {
61 this->m_kspreadView = (View*)parent;
62 }
63 else
64 {
65 kdWarning() << "Parent does not inherit View!!!" << endl;
66 }
67 }
68 else
69 {
70 kdWarning() << "Plugin created without a parent!!!" << endl;
71 }
72
73
74 this->m_dialog = NULL;
75
76 (void)new TDEAction( i18n("Insert Calendar..."), TDEShortcut::null(),
77 this, TQ_SLOT( slotShowDialog() ), actionCollection(), "kspreadinsertcalendar");
78}
79
80PluginInsertCalendar::~PluginInsertCalendar()
81{
82}
83
84TDEAboutData* PluginInsertCalendar::createAboutData()
85{
86 TDEAboutData * aboutData = new TDEAboutData(
87 "kspreadinsertcalendar", //app name
88 I18N_NOOP("Insert Calendar"), //program name
89 KOFFICE_VERSION_STRING, //version
90 I18N_NOOP("KSpread Insert Calendar Plugin"), //short description
91 TDEAboutData::License_BSD, //license type
92 I18N_NOOP("(c) 2005, The KSpread Team"), //copyright
93 0 ); //I18N_NOOP("The Insert Calendar plugin can be used in spreadsheets"), //text
94 aboutData->addAuthor("Raphael Langerhorst", 0, "Raphael.Langerhorst@kdemail.net");
95
96 return aboutData;
97}
98
99void PluginInsertCalendar::slotShowDialog()
100{
101 kdDebug() << "slotShowDialog..." << endl;
102
103 if (this->m_dialog == NULL)
104 {
105 this->m_dialog = new InsertCalendarDialog();
106
107 Q_ASSERT(m_dialog);
108
109 connect(m_dialog,TQ_SIGNAL(insertCalendar(const TQDate&, const TQDate&)),
110 this,TQ_SLOT(slotInsertCalendar(const TQDate&, const TQDate&)));
111 }
112
113 //@todo if anyone knows a better way to get a background window to foreground, please change this...
114 m_dialog->hide();
115 m_dialog->show();
116
117}
118
119void PluginInsertCalendar::slotInsertCalendar(const TQDate &start, const TQDate &end)
120{
121 //@todo implement
122 kdDebug() << "slotInsert... still to be implemented" << endl;
123
124 Doc* document = m_kspreadView->doc();
125
126 if (!document)
127 {
128 KMessageBox::error(NULL,i18n("Can't insert calendar because no document is set!"),i18n("Error"));
129 return;
130 }
131
132 if (end < start)
133 {
134 KMessageBox::error(NULL,i18n("End date is before start date! Please make sure that end date comes after start date."),i18n("Error"));
135 return;
136 }
137
138 if (start.daysTo(end) > 3652)
139 {
140 KMessageBox::error(NULL,i18n("Calendars shouldn't be longer than 10 years. If you really need such long periods you need to split them up."),i18n("Error"));
141 return;
142 }
143
144 if (start == end)
145 {
146 if (KMessageBox::No == KMessageBox::warningYesNo(NULL,i18n("Start and end dates are equal! Only one day will be inserted, do you want to continue?"),i18n("Warning")))
147 return;
148 }
149
150 if (start.daysTo(end)> 366)
151 {
152 if (KMessageBox::No == KMessageBox::warningYesNo(NULL,i18n("Creating a calendar for a longer period than a year can take up a lot of space, do you want to continue?"),i18n("Warning")))
153 return;
154 }
155
156 Selection* selection_info = m_kspreadView->selectionInfo();
157
158 Q_ASSERT(selection_info);
159
160 TQPoint selection = selection_info->selection().topLeft();
161
162 Sheet* sheet = m_kspreadView->activeSheet();
163
164 Q_ASSERT(sheet);
165
166 if (!sheet)
167 return;
168
169 //now let's check if the area is really empty...
170 //we use two columns per day and one column for the week number
171 int sizeX = 15;
172 //we use two rows per week, some additional space between months...
173 //so that should be ok, but can be improved of course
174 //@todo improve calendar size prediction!
175 int sizeY = 4 + (int)(0.5*(float)(start.daysTo(end)));
176
177 if (!sheet->areaIsEmpty(TQRect(selection,TQSize(sizeX,sizeY))))
178 {
179 if (KMessageBox::No == KMessageBox::warningYesNo(NULL,i18n("The area where the calendar is inserted is NOT empty, are you sure you want to continue, overwriting existing data? If you choose No the area that would be required for the desired calendar will be selected so you can see what data would be overwritten."),i18n("Warning")))
180 {
181 //select the area so the user knows what's in the way
182 selection_info->initialize(TQRect(selection.x(),selection.y(),sizeX,sizeY));//,sheet);
183 return;
184 }
185 }
186
187 KCalendarSystem* cs = KCalendarSystemFactory::create();
188
189 Q_ASSERT(cs);
190
191 document->emitBeginOperation();
192
193 int row = selection.y();
194 int col = selection.x();
195 int colstart = col; //this is where we get back after each week
196 sheet->setText(row,colstart,i18n("Calendar from %1 to %2").arg(start.toString()).arg(end.toString()));
197
198 TQDate current(start);
199// TQDate previous(current);
200 bool yearheader = true;
201 bool monthheader = true;
202 bool weekheader = true;
203
204 //this loop creates the actual calendar
205 //@todo formatting of cells - each day occupies TQRect(row,col,row,col+1)
206 while (current <= end)
207 {
208
209 //let's see if any header is required
210 if (cs->dayOfWeek(current)==1)
211 {
212 col=colstart;
213 row++;
214 weekheader=true;
215 }
216 if (cs->day(current)==1)
217 {
218 row+=2;
219 col=colstart + (cs->dayOfWeek(current)-1)*2;
220 monthheader=true;
221 weekheader=true;
222 if (cs->month(current)==1)
223 {
224 row++;
225 yearheader=true;
226 }
227 }
228
229 if (yearheader)
230 {
231 kdDebug() << "inserting year " + TQString::number(current.year()) << endl;
232 sheet->setText(row,colstart+6,cs->yearString(current,false));
233
234 row+=2;
235 yearheader=false;
236 }
237 if (monthheader)
238 {
239 kdDebug() << "inserting month " + TQString::number(current.month()) << endl;
240 sheet->setText(row,colstart+6,cs->monthName(current,false));
241 row+=2;
242 //we always have the week number in the first column
243 sheet->setText(row,colstart,i18n("week"));
244 for (int i=1; i<8; i++)
245 {
246 sheet->setText(row,colstart+(i-1)*2+1,cs->weekDayName(i));
247 }
248 row++;
249 monthheader=false;
250 }
251 if (weekheader)
252 {
253 sheet->setText(row,colstart,TQString::number(cs->weekNumber(current)));
254 col++;
255 weekheader=false;
256
257 //if we are at the beginning of the month we might need an offset
258 if (cs->day(current)==1)
259 {
260 col=colstart + (cs->dayOfWeek(current)-1)*2 + 1;
261 }
262 }
263
264 sheet->setText(row,col,TQString::number(cs->day(current)));
265 //go to the next date
266 //@todo isn't there a better way, like current++ or something??
267 TQDate next = current.addDays(1);
268 current.setYMD(next.year(),next.month(),next.day());
269 col+=2;
270
271 }
272
273 document->emitEndOperation();
274
275 kdDebug() << "inserting calendar completed" << endl;
276}
277
278}
279
280#include "kspread_plugininsertcalendar.moc"
The View class displays a KSpread document.
The KSpread namespace.
Definition commands.h:39