Ran am2cmake.
[basket4.git] / src / notecontent.cpp
blob58b68da682dd702d148ccdc384f508784353e15a
1 /***************************************************************************
2 * Copyright (C) 2003 by S�astien Laot *
3 * slaout@linux62.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include <qfile.h>
22 #include <qdir.h>
23 #include <qdom.h>
24 #include <qpainter.h>
25 #include <q3stylesheet.h>
26 #include <qfontmetrics.h>
27 #include <qwidget.h>
28 #include <qcursor.h>
29 #include <qstringlist.h>
30 #include <qbuffer.h>
31 //Added by qt3to4:
32 #include <Q3ValueList>
33 #include <QPixmap>
34 #include <ktextedit.h>
35 #include <kservice.h>
36 #include <kcolordialog.h>
37 #include <kmessagebox.h>
38 #include <klocale.h>
39 #include <kglobalsettings.h>
40 #include <kpixmapeffect.h>
41 #include <qbitmap.h>
42 #include <kurifilter.h>
43 #include <qregexp.h>
44 //#include <kstringhandler.h>
45 #include <kfilemetainfo.h>
46 #include <qdatetime.h>
47 #include <kmultipledrag.h>
49 #include <qfileinfo.h>
50 //#include <kio/kfileitem.h>
51 #include <kfileitem.h>
52 #include <kio/previewjob.h>
53 #include <kio/global.h>
55 #include <iostream>
57 #include "notecontent.h"
58 #include "note.h"
59 #include "noteedit.h"
60 #include "tag.h"
61 #include "basket.h"
62 #include "filter.h"
63 #include "xmlwork.h"
64 #include "tools.h"
65 #include "notefactory.h"
66 #include "linklabel.h"
67 #include "global.h"
68 #include "settings.h"
69 #include "focusedwidgets.h"
70 #include "debugwindow.h"
71 #include "kcolorcombo2.h"
72 #include "htmlexporter.h"
74 #include "config.h"
75 #ifndef WITHOUT_ARTS
76 #include <arts/kplayobject.h>
77 #include <arts/kplayobjectfactory.h>
78 #include <arts/kartsserver.h>
79 #include <arts/kartsdispatcher.h>
80 #endif
82 /** class NoteContent:
85 const int NoteContent::FEEDBACK_DARKING = 105;
87 NoteContent::NoteContent(Note *parent, const QString &fileName)
88 : m_note(parent)
90 parent->setContent(this);
91 setFileName(fileName);
94 void NoteContent::saveToNode(QDomDocument &doc, QDomElement &content)
96 if (useFile()) {
97 QDomText textNode = doc.createTextNode(fileName());
98 content.appendChild(textNode);
102 QRect NoteContent::zoneRect(int zone, const QPoint &/*pos*/)
104 if (zone == Note::Content)
105 return QRect(0, 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect()
106 else
107 return QRect();
110 KURL NoteContent::urlToOpen(bool /*with*/)
112 return (useFile() ? KURL(fullPath()) : KURL());
115 void NoteContent::setFileName(const QString &fileName)
117 m_fileName = fileName;
120 bool NoteContent::trySetFileName(const QString &fileName)
122 if (useFile() && fileName != m_fileName) {
123 QString newFileName = Tools::fileNameForNewFile(fileName, basket()->fullPath());
124 QDir dir;
125 dir.rename(fullPath(), basket()->fullPathForFileName(newFileName));
126 return true;
129 return false; // !useFile() or unsuccesful rename
132 QString NoteContent::fullPath()
134 if (note() && useFile())
135 return note()->fullPath();
136 else
137 return "";
140 void NoteContent::contentChanged(int newMinWidth)
142 m_minWidth = newMinWidth;
143 if (note()) {
144 // note()->unbufferize();
145 note()->requestRelayout(); // TODO: It should re-set the width! m_width = 0 ? contentChanged: setWidth, geteight, if size havent changed, only repaint and not relayout
149 Basket* NoteContent::basket()
151 if (note())
152 return note()->basket();
153 else
154 return 0;
157 void NoteContent::setEdited()
159 note()->setLastModificationDate(QDateTime::currentDateTime());
160 basket()->save();
163 /** All the Content Classes:
166 NoteType::Id TextContent::type() { return NoteType::Text; }
167 NoteType::Id HtmlContent::type() { return NoteType::Html; }
168 NoteType::Id ImageContent::type() { return NoteType::Image; }
169 NoteType::Id AnimationContent::type() { return NoteType::Animation; }
170 NoteType::Id SoundContent::type() { return NoteType::Sound; }
171 NoteType::Id FileContent::type() { return NoteType::File; }
172 NoteType::Id LinkContent::type() { return NoteType::Link; }
173 NoteType::Id LauncherContent::type() { return NoteType::Launcher; }
174 NoteType::Id ColorContent::type() { return NoteType::Color; }
175 NoteType::Id UnknownContent::type() { return NoteType::Unknown; }
177 QString TextContent::typeName() { return i18n("Plain Text"); }
178 QString HtmlContent::typeName() { return i18n("Text"); }
179 QString ImageContent::typeName() { return i18n("Image"); }
180 QString AnimationContent::typeName() { return i18n("Animation"); }
181 QString SoundContent::typeName() { return i18n("Sound"); }
182 QString FileContent::typeName() { return i18n("File"); }
183 QString LinkContent::typeName() { return i18n("Link"); }
184 QString LauncherContent::typeName() { return i18n("Launcher"); }
185 QString ColorContent::typeName() { return i18n("Color"); }
186 QString UnknownContent::typeName() { return i18n("Unknown"); }
188 QString TextContent::lowerTypeName() { return "text"; }
189 QString HtmlContent::lowerTypeName() { return "html"; }
190 QString ImageContent::lowerTypeName() { return "image"; }
191 QString AnimationContent::lowerTypeName() { return "animation"; }
192 QString SoundContent::lowerTypeName() { return "sound"; }
193 QString FileContent::lowerTypeName() { return "file"; }
194 QString LinkContent::lowerTypeName() { return "link"; }
195 QString LauncherContent::lowerTypeName() { return "launcher"; }
196 QString ColorContent::lowerTypeName() { return "color"; }
197 QString UnknownContent::lowerTypeName() { return "unknown"; }
199 QString NoteContent::toText(const QString &cuttedFullPath)
201 return (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath);
204 QString TextContent::toText(const QString &/*cuttedFullPath*/) { return text(); }
205 QString HtmlContent::toText(const QString &/*cuttedFullPath*/) { return Tools::htmlToText(html()); }
206 QString LinkContent::toText(const QString &/*cuttedFullPath*/)
208 if (autoTitle())
209 return url().prettyURL();
210 else if (title().isEmpty() && url().isEmpty())
211 return "";
212 else if (url().isEmpty())
213 return title();
214 else if (title().isEmpty())
215 return url().prettyURL();
216 else
217 return QString("%1 <%2>").arg(title(), url().prettyURL());
219 QString ColorContent::toText(const QString &/*cuttedFullPath*/) { return color().name(); }
220 QString UnknownContent::toText(const QString &/*cuttedFullPath*/) { return ""; }
222 // TODO: If imageName.isEmpty() return fullPath() because it's for external use, else return fileName() because it's to display in a tooltip
223 QString TextContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/)
224 { return Tools::textToHTMLWithoutP(text()); }
226 QString HtmlContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/)
227 { return Tools::htmlToParagraph(html()); }
229 QString ImageContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath)
230 { return QString("<img src=\"%1\">").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); }
232 QString AnimationContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath)
233 { return QString("<img src=\"%1\">").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); }
235 QString SoundContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath)
236 { return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon?
238 QString FileContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath)
239 { return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon?
241 QString LinkContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/)
242 { return QString("<a href=\"%1\">%2</a>").arg(url().prettyURL(), title()); } // With the icon?
244 QString LauncherContent::toHtml(const QString &/*imageName*/, const QString &cuttedFullPath)
245 { return QString("<a href=\"%1\">%2</a>").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), name()); } // With the icon?
247 QString ColorContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/)
248 { return QString("<span style=\"color: %1\">%2</span>").arg(color().name(), color().name()); }
250 QString UnknownContent::toHtml(const QString &/*imageName*/, const QString &/*cuttedFullPath*/)
251 { return ""; }
253 QPixmap ImageContent::toPixmap() { return pixmap(); }
254 QPixmap AnimationContent::toPixmap() { return movie().framePixmap(); }
256 void NoteContent::toLink(KURL *url, QString *title, const QString &cuttedFullPath)
258 if (useFile()) {
259 *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath);
260 *title = (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath);
261 } else {
262 *url = KURL();
263 *title = QString();
266 void LinkContent::toLink(KURL *url, QString *title, const QString &/*cuttedFullPath*/)
268 *url = this->url();
269 *title = this->title();
272 void LauncherContent::toLink(KURL *url, QString *title, const QString &cuttedFullPath)
274 *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath);
275 *title = name();
277 void UnknownContent::toLink(KURL *url, QString *title, const QString &/*cuttedFullPath*/)
279 *url = KURL();
280 *title = QString();
283 bool TextContent::useFile() { return true; }
284 bool HtmlContent::useFile() { return true; }
285 bool ImageContent::useFile() { return true; }
286 bool AnimationContent::useFile() { return true; }
287 bool SoundContent::useFile() { return true; }
288 bool FileContent::useFile() { return true; }
289 bool LinkContent::useFile() { return false; }
290 bool LauncherContent::useFile() { return true; }
291 bool ColorContent::useFile() { return false; }
292 bool UnknownContent::useFile() { return true; }
294 bool TextContent::canBeSavedAs() { return true; }
295 bool HtmlContent::canBeSavedAs() { return true; }
296 bool ImageContent::canBeSavedAs() { return true; }
297 bool AnimationContent::canBeSavedAs() { return true; }
298 bool SoundContent::canBeSavedAs() { return true; }
299 bool FileContent::canBeSavedAs() { return true; }
300 bool LinkContent::canBeSavedAs() { return true; }
301 bool LauncherContent::canBeSavedAs() { return true; }
302 bool ColorContent::canBeSavedAs() { return false; }
303 bool UnknownContent::canBeSavedAs() { return false; }
305 QString TextContent::saveAsFilters() { return "text/plain"; }
306 QString HtmlContent::saveAsFilters() { return "text/html"; }
307 QString ImageContent::saveAsFilters() { return "image/png"; } // TODO: Offer more types
308 QString AnimationContent::saveAsFilters() { return "image/gif"; } // TODO: MNG...
309 QString SoundContent::saveAsFilters() { return "audio/x-mp3"; } // TODO: OGG...
310 QString FileContent::saveAsFilters() { return "*"; } // TODO: Get MIME type of the url target
311 QString LinkContent::saveAsFilters() { return "*"; } // TODO: idem File + If isDir(): return
312 QString LauncherContent::saveAsFilters() { return "application/x-desktop"; }
313 QString ColorContent::saveAsFilters() { return ""; }
314 QString UnknownContent::saveAsFilters() { return ""; }
316 bool TextContent::match(const FilterData &data) { return (text().find(data.string, /*index=*/0, /*cs=*/false) != -1); }
317 bool HtmlContent::match(const FilterData &data) { return (m_textEquivalent/*toText("")*/.find(data.string, /*index=*/0, /*cs=*/false) != -1); } //OPTIM_FILTER
318 bool ImageContent::match(const FilterData &/*data*/) { return false; }
319 bool AnimationContent::match(const FilterData &/*data*/) { return false; }
320 bool SoundContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); }
321 bool FileContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); }
322 bool LinkContent::match(const FilterData &data) { return (title().find(data.string, 0, false) != -1 || url().prettyURL().find(data.string, 0, false) != -1); }
323 bool LauncherContent::match(const FilterData &data) { return (exec().find(data.string, 0, false) != -1 || name().find(data.string, 0, false) != -1); }
324 bool ColorContent::match(const FilterData &data) { return (color().name().find(data.string, /*index=*/0, /*cs=*/false) != -1); }
325 bool UnknownContent::match(const FilterData &data) { return (mimeTypes().find(data.string, /*index=*/0, /*cs=*/false) != -1); }
327 QString TextContent::editToolTipText() { return i18n("Edit this plain text"); }
328 QString HtmlContent::editToolTipText() { return i18n("Edit this text"); }
329 QString ImageContent::editToolTipText() { return i18n("Edit this image"); }
330 QString AnimationContent::editToolTipText() { return i18n("Edit this animation"); }
331 QString SoundContent::editToolTipText() { return i18n("Edit the file name of this sound"); }
332 QString FileContent::editToolTipText() { return i18n("Edit the name of this file"); }
333 QString LinkContent::editToolTipText() { return i18n("Edit this link"); }
334 QString LauncherContent::editToolTipText() { return i18n("Edit this launcher"); }
335 QString ColorContent::editToolTipText() { return i18n("Edit this color"); }
336 QString UnknownContent::editToolTipText() { return i18n("Edit this unknown object"); }
338 QString TextContent::cssClass() { return ""; }
339 QString HtmlContent::cssClass() { return ""; }
340 QString ImageContent::cssClass() { return ""; }
341 QString AnimationContent::cssClass() { return ""; }
342 QString SoundContent::cssClass() { return "sound"; }
343 QString FileContent::cssClass() { return "file"; }
344 QString LinkContent::cssClass() { return (LinkLook::lookForURL(m_url) == LinkLook::localLinkLook ? "local" : "network"); }
345 QString LauncherContent::cssClass() { return "launcher"; }
346 QString ColorContent::cssClass() { return "" ; }
347 QString UnknownContent::cssClass() { return ""; }
349 void TextContent::fontChanged() { setText(text()); }
350 void HtmlContent::fontChanged() { setHtml(html()); }
351 void ImageContent::fontChanged() { setPixmap(pixmap()); }
352 void AnimationContent::fontChanged() { setMovie(movie()); }
353 void FileContent::fontChanged() { setFileName(fileName()); }
354 void LinkContent::fontChanged() { setLink(url(), title(), icon(), autoTitle(), autoIcon()); }
355 void LauncherContent::fontChanged() { setLauncher(name(), icon(), exec()); }
356 void ColorContent::fontChanged() { setColor(color()); }
357 void UnknownContent::fontChanged() { loadFromFile(/*lazyLoad=*/false); } // TODO: Optimize: setMimeTypes()
359 //QString TextContent::customOpenCommand() { return (Settings::isTextUseProg() && ! Settings::textProg().isEmpty() ? Settings::textProg() : QString()); }
360 QString HtmlContent::customOpenCommand() { return (Settings::isHtmlUseProg() && ! Settings::htmlProg().isEmpty() ? Settings::htmlProg() : QString()); }
361 QString ImageContent::customOpenCommand() { return (Settings::isImageUseProg() && ! Settings::imageProg().isEmpty() ? Settings::imageProg() : QString()); }
362 QString AnimationContent::customOpenCommand() { return (Settings::isAnimationUseProg() && ! Settings::animationProg().isEmpty() ? Settings::animationProg() : QString()); }
363 QString SoundContent::customOpenCommand() { return (Settings::isSoundUseProg() && ! Settings::soundProg().isEmpty() ? Settings::soundProg() : QString()); }
365 void LinkContent::serialize(QDataStream &stream) { stream << url() << title() << icon() << (Q_UINT64)autoTitle() << (Q_UINT64)autoIcon(); }
366 void ColorContent::serialize(QDataStream &stream) { stream << color(); }
368 QPixmap TextContent::feedbackPixmap(int width, int height)
370 QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, width, height, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, text());
371 QPixmap pixmap( QMIN(width, textRect.width()), QMIN(height, textRect.height()) );
372 pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING));
373 QPainter painter(&pixmap);
374 painter.setPen(note()->textColor());
375 painter.setFont(note()->font());
376 painter.drawText(0, 0, pixmap.width(), pixmap.height(), Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, text());
377 painter.end();
378 return pixmap;
381 QPixmap HtmlContent::feedbackPixmap(int width, int height)
383 Q3SimpleRichText richText(html(), note()->font());
384 richText.setWidth(width);
385 QColorGroup colorGroup(basket()->colorGroup());
386 colorGroup.setColor(QColorGroup::Text, note()->textColor());
387 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
388 QPixmap pixmap( QMIN(width, richText.widthUsed()), QMIN(height, richText.height()) );
389 pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING));
390 QPainter painter(&pixmap);
391 painter.setPen(note()->textColor());
392 richText.draw(&painter, 0, 0, QRect(0, 0, pixmap.width(), pixmap.height()), colorGroup);
393 painter.end();
394 return pixmap;
397 QPixmap ImageContent::feedbackPixmap(int width, int height)
399 if (width >= m_pixmap.width() && height >= m_pixmap.height()) { // Full size
400 if (m_pixmap.hasAlpha()) {
401 QPixmap opaque(m_pixmap.width(), m_pixmap.height());
402 opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING));
403 QPainter painter(&opaque);
404 painter.drawPixmap(0, 0, m_pixmap);
405 painter.end();
406 return opaque;
407 } else
408 return m_pixmap;
409 } else { // Scalled down
410 QImage imageToScale = m_pixmap.convertToImage();
411 QPixmap pmScaled;
412 pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, QImage::ScaleMin));
413 if (pmScaled.hasAlpha()) {
414 QPixmap opaque(pmScaled.width(), pmScaled.height());
415 opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING));
416 QPainter painter(&opaque);
417 painter.drawPixmap(0, 0, pmScaled);
418 painter.end();
419 return opaque;
420 } else
421 return pmScaled;
425 QPixmap AnimationContent::feedbackPixmap(int width, int height)
427 QPixmap pixmap = m_movie.framePixmap();
428 if (width >= pixmap.width() && height >= pixmap.height()) // Full size
429 return pixmap;
430 else { // Scalled down
431 QImage imageToScale = pixmap.convertToImage();
432 QPixmap pmScaled;
433 pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, QImage::ScaleMin));
434 return pmScaled;
438 QPixmap LinkContent::feedbackPixmap(int width, int height)
440 QColorGroup colorGroup(basket()->colorGroup());
441 colorGroup.setColor(QColorGroup::Text, note()->textColor());
442 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
443 return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor());
446 QPixmap ColorContent::feedbackPixmap(int width, int height)
448 // TODO: Duplicate code: make a rect() method!
449 QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name());
450 int rectHeight = (textRect.height() + 2)*3/2;
451 int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers.
453 QColorGroup colorGroup(basket()->colorGroup());
454 colorGroup.setColor(QColorGroup::Text, note()->textColor());
455 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
457 QPixmap pixmap( QMIN(width, rectWidth + RECT_MARGIN + textRect.width() + RECT_MARGIN), QMIN(height, rectHeight) );
458 pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING));
459 QPainter painter(&pixmap);
460 paint(&painter, pixmap.width(), pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters.
461 painter.end();
462 return pixmap;
465 QPixmap FileContent::feedbackPixmap(int width, int height)
467 QColorGroup colorGroup(basket()->colorGroup());
468 colorGroup.setColor(QColorGroup::Text, note()->textColor());
469 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
470 return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor());
473 QPixmap LauncherContent::feedbackPixmap(int width, int height)
475 QColorGroup colorGroup(basket()->colorGroup());
476 colorGroup.setColor(QColorGroup::Text, note()->textColor());
477 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
478 return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor());
481 QPixmap UnknownContent::feedbackPixmap(int width, int height)
483 QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes);
485 QColorGroup colorGroup(basket()->colorGroup());
486 colorGroup.setColor(QColorGroup::Text, note()->textColor());
487 colorGroup.setColor(QColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING));
489 QPixmap pixmap( QMIN(width, DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN), QMIN(height, DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN) );
490 QPainter painter(&pixmap);
491 paint(&painter, pixmap.width() + 1, pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters.
492 painter.setPen(note()->backgroundColor().dark(FEEDBACK_DARKING));
493 painter.drawPoint(0, 0);
494 painter.drawPoint(pixmap.width() - 1, 0);
495 painter.drawPoint(0, pixmap.height() - 1);
496 painter.drawPoint(pixmap.width() - 1, pixmap.height() - 1);
497 painter.end();
498 return pixmap;
502 /** class TextContent:
505 TextContent::TextContent(Note *parent, const QString &fileName, bool lazyLoad)
506 : NoteContent(parent, fileName), m_simpleRichText(0)
508 basket()->addWatchedFile(fullPath());
509 loadFromFile(lazyLoad);
512 TextContent::~TextContent()
514 delete m_simpleRichText;
517 int TextContent::setWidthAndGetHeight(int width)
519 if (m_simpleRichText) {
520 width -= 1;
521 m_simpleRichText->setWidth(width);
522 return m_simpleRichText->height();
523 } else
524 return 10; // Lazy loaded
527 void TextContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
529 if (m_simpleRichText) {
530 width -= 1;
531 m_simpleRichText->draw(painter, 0, 0, QRect(0, 0, width, height), colorGroup);
535 bool TextContent::loadFromFile(bool lazyLoad)
537 DEBUG_WIN << "Loading TextContent From " + basket()->folderName() + fileName();
539 QString content;
540 bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true);
542 if (success)
543 setText(content, lazyLoad);
544 else {
545 std::cout << "FAILED TO LOAD TextContent: " << fullPath() << std::endl;
546 setText("", lazyLoad);
547 if (!QFile::exists(fullPath()))
548 saveToFile(); // Reserve the fileName so no new note will have the same name!
550 return success;
553 bool TextContent::finishLazyLoad()
555 int width = (m_simpleRichText ? m_simpleRichText->width() : 1);
556 delete m_simpleRichText;
557 QString html = "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>" + Tools::tagURLs(Tools::textToHTML(m_text)); // Don't collapse multiple spaces!
558 m_simpleRichText = new Q3SimpleRichText(html, note()->font());
559 m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width
560 int minWidth = m_simpleRichText->widthUsed();
561 m_simpleRichText->setWidth(width);
562 contentChanged(minWidth + 1);
564 return true;
567 bool TextContent::saveToFile()
569 return basket()->saveToFile(fullPath(), text(), /*isLocalEncoding=*/true);
572 QString TextContent::linkAt(const QPoint &pos)
574 if (m_simpleRichText)
575 return m_simpleRichText->anchorAt(pos);
576 else
577 return ""; // Lazy loaded
581 QString TextContent::messageWhenOpenning(OpenMessage where)
583 switch (where) {
584 case OpenOne: return i18n("Opening plain text...");
585 case OpenSeveral: return i18n("Opening plain texts...");
586 case OpenOneWith: return i18n("Opening plain text with...");
587 case OpenSeveralWith: return i18n("Opening plain texts with...");
588 case OpenOneWithDialog: return i18n("Open plain text with:");
589 case OpenSeveralWithDialog: return i18n("Open plain texts with:");
590 default: return "";
594 void TextContent::setText(const QString &text, bool lazyLoad)
596 m_text = text;
597 if (!lazyLoad)
598 finishLazyLoad();
599 else
600 contentChanged(10);
603 void TextContent::exportToHTML(HTMLExporter *exporter, int indent)
605 QString spaces;
606 QString html = "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body>" +
607 Tools::tagURLs(Tools::textToHTMLWithoutP(text().replace("\t", " "))); // Don't collapse multiple spaces!
608 exporter->stream << html.replace(" ", " &nbsp;").replace("\n", "\n" + spaces.fill(' ', indent + 1));
611 /** class HtmlContent:
614 HtmlContent::HtmlContent(Note *parent, const QString &fileName, bool lazyLoad)
615 : NoteContent(parent, fileName), m_simpleRichText(0)
617 basket()->addWatchedFile(fullPath());
618 loadFromFile(lazyLoad);
621 HtmlContent::~HtmlContent()
623 delete m_simpleRichText;
626 int HtmlContent::setWidthAndGetHeight(int width)
628 if (m_simpleRichText) {
629 width -= 1;
630 m_simpleRichText->setWidth(width);
631 return m_simpleRichText->height();
632 } else
633 return 10; // Lazy loaded
636 void HtmlContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
638 if (m_simpleRichText) {
639 width -= 1;
640 m_simpleRichText->draw(painter, 0, 0, QRect(0, 0, width, height), colorGroup);
644 bool HtmlContent::loadFromFile(bool lazyLoad)
646 DEBUG_WIN << "Loading HtmlContent From " + basket()->folderName() + fileName();
648 QString content;
649 bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true);
651 if (success)
652 setHtml(content, lazyLoad);
653 else {
654 std::cout << "FAILED TO LOAD HtmlContent: " << fullPath() << std::endl;
655 setHtml("", lazyLoad);
656 if (!QFile::exists(fullPath()))
657 saveToFile(); // Reserve the fileName so no new note will have the same name!
659 return success;
662 bool HtmlContent::finishLazyLoad()
664 int width = (m_simpleRichText ? m_simpleRichText->width() : 1);
665 delete m_simpleRichText;
666 m_simpleRichText = new Q3SimpleRichText(Tools::tagURLs(m_html), note()->font());
667 m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width
668 int minWidth = m_simpleRichText->widthUsed();
669 m_simpleRichText->setWidth(width);
670 contentChanged(minWidth + 1);
672 return true;
675 bool HtmlContent::saveToFile()
677 return basket()->saveToFile(fullPath(), html(), /*isLocalEncoding=*/true);
680 QString HtmlContent::linkAt(const QPoint &pos)
682 if (m_simpleRichText)
683 return m_simpleRichText->anchorAt(pos);
684 else
685 return ""; // Lazy loaded
689 QString HtmlContent::messageWhenOpenning(OpenMessage where)
691 switch (where) {
692 case OpenOne: return i18n("Opening text...");
693 case OpenSeveral: return i18n("Opening texts...");
694 case OpenOneWith: return i18n("Opening text with...");
695 case OpenSeveralWith: return i18n("Opening texts with...");
696 case OpenOneWithDialog: return i18n("Open text with:");
697 case OpenSeveralWithDialog: return i18n("Open texts with:");
698 default: return "";
702 void HtmlContent::setHtml(const QString &html, bool lazyLoad)
704 m_html = html;
705 m_textEquivalent = toText(""); //OPTIM_FILTER
706 if (!lazyLoad)
707 finishLazyLoad();
708 else
709 contentChanged(10);
712 void HtmlContent::exportToHTML(HTMLExporter *exporter, int indent)
714 QString spaces;
715 exporter->stream << Tools::htmlToParagraph(Tools::tagURLs(html().replace("\t", " ")))
716 .replace(" ", " &nbsp;")
717 .replace("\n", "\n" + spaces.fill(' ', indent + 1));
720 /** class ImageContent:
723 ImageContent::ImageContent(Note *parent, const QString &fileName, bool lazyLoad)
724 : NoteContent(parent, fileName), m_format(0)
726 basket()->addWatchedFile(fullPath());
727 loadFromFile(lazyLoad);
730 int ImageContent::setWidthAndGetHeight(int width)
732 width -= 1;
733 // Don't store width: we will get it on paint!
734 if (width >= m_pixmap.width()) // Full size
735 return m_pixmap.height();
736 else { // Scalled down
737 double height = m_pixmap.height() * (double)width / m_pixmap.width();
738 return int((double)(int)height <= (height - 0.5) ? height + 1 : height);
742 void ImageContent::paint(QPainter *painter, int width, int /*height*/, const QColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
744 width -= 1;
745 // KPixmap pixmap = m_pixmap;
746 // if (note()->isSelected())
747 // pixmap = KPixmapEffect::selectedPixmap(m_pixmap, KGlobalSettings::highlightColor());
749 if (width >= m_pixmap.width()) // Full size
750 painter->drawPixmap(0, 0, m_pixmap);
751 else { // Scalled down
752 double scale = ((double)width) / m_pixmap.width();
753 painter->scale(scale, scale);
754 painter->drawPixmap(0, 0, m_pixmap); // TODO: Smooth !!!
758 bool ImageContent::loadFromFile(bool lazyLoad)
760 if (lazyLoad)
761 return true;
762 else
763 return finishLazyLoad();
766 bool ImageContent::finishLazyLoad()
768 DEBUG_WIN << "Loading ImageContent From " + basket()->folderName() + fileName();
770 QByteArray content;
772 if (basket()->loadFromFile(fullPath(), &content))
774 QBuffer buffer(content);
776 buffer.open(QIODevice::ReadOnly);
777 m_format = (char* /* from const char* */)QImageIO::imageFormat(&buffer); // See QImageIO to know what formats can be supported.
778 buffer.close();
779 if (m_format) {
780 m_pixmap.loadFromData(content);
781 setPixmap(m_pixmap);
782 return true;
786 std::cout << "FAILED TO LOAD ImageContent: " << fullPath() << std::endl;
787 m_format = (char*)"PNG"; // If the image is set later, it should be saved without destruction, so we use PNG by default.
788 m_pixmap.resize(1, 1); // Create a 1x1 pixels image instead of an undefined one.
789 m_pixmap.fill();
790 m_pixmap.setMask(m_pixmap.createHeuristicMask());
791 setPixmap(m_pixmap);
792 if (!QFile::exists(fullPath()))
793 saveToFile(); // Reserve the fileName so no new note will have the same name!
794 return false;
797 bool ImageContent::saveToFile()
799 QByteArray ba;
800 QBuffer buffer(ba);
802 buffer.open(QIODevice::WriteOnly);
803 m_pixmap.save(&buffer, m_format);
804 return basket()->saveToFile(fullPath(), ba);
808 void ImageContent::toolTipInfos(QStringList *keys, QStringList *values)
810 keys->append(i18n("Size"));
811 values->append(i18n("%1 by %2 pixels").arg(QString::number(m_pixmap.width()), QString::number(m_pixmap.height())));
814 QString ImageContent::messageWhenOpenning(OpenMessage where)
816 switch (where) {
817 case OpenOne: return i18n("Opening image...");
818 case OpenSeveral: return i18n("Opening images...");
819 case OpenOneWith: return i18n("Opening image with...");
820 case OpenSeveralWith: return i18n("Opening images with...");
821 case OpenOneWithDialog: return i18n("Open image with:");
822 case OpenSeveralWithDialog: return i18n("Open images with:");
823 default: return "";
827 void ImageContent::setPixmap(const QPixmap &pixmap)
829 m_pixmap = pixmap;
830 // Since it's scalled, the height is always greater or equal to the size of the tag emblems (16)
831 contentChanged(16 + 1); // TODO: always good? I don't think...
834 void ImageContent::exportToHTML(HTMLExporter *exporter, int /*indent*/)
836 int width = m_pixmap.width();
837 int height = m_pixmap.height();
838 int contentWidth = note()->width() - note()->contentX() - 1 - Note::NOTE_MARGIN;
840 QString imageName = exporter->copyFile(fullPath(), /*createIt=*/true);
842 if (contentWidth <= m_pixmap.width()) { // Scalled down
843 double scale = ((double)contentWidth) / m_pixmap.width();
844 width = (int)(m_pixmap.width() * scale);
845 height = (int)(m_pixmap.height() * scale);
846 exporter->stream << "<a href=\"" << exporter->dataFolderName << imageName << "\" title=\"" << i18n("Click for full size view") << "\">";
849 exporter->stream << "<img src=\"" << exporter->dataFolderName << imageName
850 << "\" width=\"" << width << "\" height=\"" << height << "\" alt=\"\">";
852 if (contentWidth <= m_pixmap.width()) // Scalled down
853 exporter->stream << "</a>";
856 /** class AnimationContent:
859 int AnimationContent::INVALID_STATUS = -100;
861 AnimationContent::AnimationContent(Note *parent, const QString &fileName, bool lazyLoad)
862 : NoteContent(parent, fileName), m_oldStatus(INVALID_STATUS)
864 basket()->addWatchedFile(fullPath());
865 loadFromFile(lazyLoad);
868 int AnimationContent::setWidthAndGetHeight(int /*width*/)
870 /*width -= 1*/;
871 return m_movie.framePixmap().height() ; // TODO!!!
874 void AnimationContent::paint(QPainter *painter, int width, int /*height*/, const QColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
876 /*width -= 1*/;
877 // DEBUG_WIN << "AnimationContent::paint()";
878 const QPixmap &frame = m_movie.framePixmap();
879 if (width >= frame.width()) // Full size
880 painter->drawPixmap(0, 0, frame);
881 else // Scalled down
882 painter->drawPixmap(0, 0, frame); // TODO: Scall down
885 bool AnimationContent::loadFromFile(bool lazyLoad)
887 if (lazyLoad)
888 return true;
889 else
890 return finishLazyLoad();
893 bool AnimationContent::finishLazyLoad()
895 DEBUG_WIN << "Loading MovieContent From " + basket()->folderName() + fileName();
896 // return setMovie(QMovie(fullPath()));
898 bool success = false;
899 QByteArray content;
900 if (basket()->loadFromFile(fullPath(), &content))
901 success = setMovie(QMovie(content, content.size()));
902 if (!success)
903 setMovie(QMovie());
904 return success;
907 bool AnimationContent::saveToFile()
909 // Impossible!
910 return false;
914 QString AnimationContent::messageWhenOpenning(OpenMessage where)
916 switch (where) {
917 case OpenOne: return i18n("Opening animation...");
918 case OpenSeveral: return i18n("Opening animations...");
919 case OpenOneWith: return i18n("Opening animation with...");
920 case OpenSeveralWith: return i18n("Opening animations with...");
921 case OpenOneWithDialog: return i18n("Open animation with:");
922 case OpenSeveralWithDialog: return i18n("Open animations with:");
923 default: return "";
927 bool AnimationContent::setMovie(const QMovie &movie)
929 if (!m_movie.isNull()) {
930 // Disconnect?
931 return false;
933 m_movie = movie;
934 m_movie.connectUpdate( this, SLOT(movieUpdated(const QRect&)) );
935 m_movie.connectResize( this, SLOT(movieResized(const QSize&)) );
936 m_movie.connectStatus( this, SLOT(movieStatus(int)) );
937 contentChanged( m_movie.framePixmap().width() + 1 ); // TODO
938 return true;
941 void AnimationContent::movieUpdated(const QRect&)
943 note()->unbufferize();
944 note()->update();
947 void AnimationContent::movieResized(const QSize&)
949 note()->requestRelayout(); // ?
952 /** When a user drop a .gif file, for instance, we don't know if it is an image
953 * or an animtion (gif file contain multiple images).
954 * To determin that, we assume this is an animation and count the number of images.
955 * QMovie send, in this order:
956 * - For a unique image: QMovie::EndOfFrame, QMovie::EndOfLoop, QMovie::EndOfMovie.
957 * - For animation: QMovie::EndOfFrame... (for each image), QMovie::EndOfLoop,
958 * and it then restart that for each loop.
960 void AnimationContent::movieStatus(int status)
962 DEBUG_WIN << "movieStatus()";
964 // At least two frames: it's an animation, everything is OK
965 if (m_oldStatus == QMovie::EndOfFrame && status == QMovie::EndOfFrame) {
966 movie().disconnectStatus(this);
967 m_oldStatus = INVALID_STATUS;
968 // if (note()->isFocused()) // When inserting a new note we ensure it visble
969 // basket()->ensureNoteVisible(note()); // But after loading it has certainly grown and if it was
971 // Only one image: it's an image, change note's type
972 else if (m_oldStatus == QMovie::EndOfFrame && status == QMovie::EndOfLoop) {
973 movie().disconnectStatus(this);
974 m_oldStatus = INVALID_STATUS;
975 note()->setContent(new ImageContent(note(), fileName()));
976 basket()->save();
977 //delete this; // CRASH, as always !!!!!!!!!
978 //QTimer::singleShot(0, this, SLOT(loadContent())); // Delayed to avoid crash!
979 //QTimer::singleShot(100, this, SLOT(saveProperties())); // We should save it's an image and not an animation
980 // if (note()->isFocused())
981 // QTimer::singleShot(25, note(), SLOT(delayedEnsureVisible()));
983 else
984 m_oldStatus = status;
987 void AnimationContent::exportToHTML(HTMLExporter *exporter, int /*indent*/)
989 exporter->stream << QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">")
990 .arg( exporter->dataFolderName + exporter->copyFile(fullPath(), /*createIt=*/true),
991 QString::number(movie().framePixmap().size().width()),
992 QString::number(movie().framePixmap().size().height()) );
995 /** class FileContent:
998 FileContent::FileContent(Note *parent, const QString &fileName)
999 : NoteContent(parent, fileName), m_previewJob(0)
1001 basket()->addWatchedFile(fullPath());
1002 setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods???
1005 int FileContent::setWidthAndGetHeight(int width)
1007 m_linkDisplay.setWidth(width);
1008 return m_linkDisplay.height();
1011 void FileContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered)
1013 m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0);
1016 bool FileContent::loadFromFile(bool /*lazyLoad*/)
1018 setFileName(fileName()); // File changed: get new file preview!
1019 return true;
1022 void FileContent::toolTipInfos(QStringList *keys, QStringList *values)
1024 // Get the size of the file:
1025 uint size = QFileInfo(fullPath()).size();
1026 QString humanFileSize = KIO::convertSize((KIO::filesize_t)size);
1028 keys->append(i18n("Size"));
1029 values->append(humanFileSize);
1031 KMimeType::Ptr mime = KMimeType::findByURL(KURL(fullPath()));
1032 if (mime) {
1033 keys->append(i18n("Type"));
1034 values->append(mime->comment());
1037 KFileMetaInfo infos = KFileMetaInfo(KURL(fullPath()));
1038 if (infos.isValid() && !infos.isEmpty()) {
1039 QStringList groups = infos.preferredKeys();
1040 int i = 0;
1041 for (QStringList::Iterator it = groups.begin(); i < 6 && it != groups.end(); ++it) {
1042 KFileMetaInfoItem metaInfoItem = infos.item(*it);
1043 if (!metaInfoItem.string().isEmpty()) {
1044 keys->append(metaInfoItem.translatedKey());
1045 values->append(metaInfoItem.string());
1046 ++i;
1052 int FileContent::zoneAt(const QPoint &pos)
1054 return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0);
1057 QRect FileContent::zoneRect(int zone, const QPoint &/*pos*/)
1059 QRect linkRect = m_linkDisplay.iconButtonRect();
1061 if (zone == Note::Custom0)
1062 return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect()
1063 else if (zone == Note::Content)
1064 return linkRect;
1065 else
1066 return QRect();
1069 QString FileContent::zoneTip(int zone)
1071 return (zone == Note::Custom0 ? i18n("Open this file") : QString());
1074 void FileContent::setCursor(QWidget *widget, int zone)
1076 if (zone == Note::Custom0)
1077 widget->setCursor(Qt::PointingHandCursor);
1081 int FileContent::xEditorIndent()
1083 return m_linkDisplay.iconButtonRect().width() + 2;
1087 QString FileContent::messageWhenOpenning(OpenMessage where)
1089 switch (where) {
1090 case OpenOne: return i18n("Opening file...");
1091 case OpenSeveral: return i18n("Opening files...");
1092 case OpenOneWith: return i18n("Opening file with...");
1093 case OpenSeveralWith: return i18n("Opening files with...");
1094 case OpenOneWithDialog: return i18n("Open file with:");
1095 case OpenSeveralWithDialog: return i18n("Open files with:");
1096 default: return "";
1100 void FileContent::setFileName(const QString &fileName)
1102 NoteContent::setFileName(fileName);
1103 KURL url = KURL(fullPath());
1104 if (linkLook()->previewEnabled())
1105 m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), linkLook(), note()->font()); // FIXME: move iconForURL outside of NoteFactory !!!!!
1106 else
1107 m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), QPixmap(), linkLook(), note()->font());
1108 startFetchingUrlPreview();
1109 contentChanged(m_linkDisplay.minWidth());
1112 void FileContent::linkLookChanged()
1114 fontChanged();
1115 //setFileName(fileName());
1116 //startFetchingUrlPreview();
1119 void FileContent::newPreview(const KFileItem*, const QPixmap &preview)
1121 LinkLook *linkLook = this->linkLook();
1122 m_linkDisplay.setLink(fileName(), NoteFactory::iconForURL(KURL(fullPath())), (linkLook->previewEnabled() ? preview : QPixmap()), linkLook, note()->font());
1123 contentChanged(m_linkDisplay.minWidth());
1126 void FileContent::removePreview(const KFileItem*)
1128 newPreview(0, QPixmap());
1131 void FileContent::startFetchingUrlPreview()
1133 KURL url(fullPath());
1134 LinkLook *linkLook = this->linkLook();
1136 // delete m_previewJob;
1137 if (!url.isEmpty() && linkLook->previewSize() > 0) {
1138 KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url);
1139 KURL::List urlList;
1140 urlList.append(filteredUrl);
1141 m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize());
1142 connect( m_previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), this, SLOT(newPreview(const KFileItem*, const QPixmap&)) );
1143 connect( m_previewJob, SIGNAL(failed(const KFileItem*)), this, SLOT(removePreview(const KFileItem*)) );
1147 void FileContent::exportToHTML(HTMLExporter *exporter, int indent)
1149 QString spaces;
1150 QString fileName = exporter->copyFile(fullPath(), true);
1151 exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1));
1154 /** class SoundContent:
1157 SoundContent::SoundContent(Note *parent, const QString &fileName)
1158 : FileContent(parent, fileName)
1160 setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods???
1164 QString SoundContent::zoneTip(int zone)
1166 return (zone == Note::Custom0 ? i18n("Open this sound") : QString());
1169 void SoundContent::setHoveredZone(int oldZone, int newZone)
1171 #ifdef WITHOUT_ARTS
1172 Q_UNUSED(oldZone);
1173 if (newZone == Note::Custom0 || newZone == Note::Content)
1174 std::cout << "Compiled without aRts: sound is not played." << std::endl;
1175 #else
1176 static KArtsDispatcher *s_dispatcher = new KArtsDispatcher(); // Needed for s_playObj (we don't use it directly)
1177 static KArtsServer *s_playServer = new KArtsServer();
1178 static KDE::PlayObjectFactory *s_playFactory = new KDE::PlayObjectFactory(s_playServer);
1179 static KDE::PlayObject *s_playObj = 0;
1181 Q_UNUSED(s_dispatcher); // Avoid the compiler to tell us it is not used!
1182 if (newZone == Note::Custom0 || newZone == Note::Content) {
1183 // Start the sound preview:
1184 if (oldZone != Note::Custom0 && oldZone != Note::Content) { // Don't restart if it was already in one of those zones
1185 s_playObj = s_playFactory->createPlayObject(fullPath(), true);
1186 s_playObj->play();
1188 } else {
1189 // Stop the sound preview, if it was started:
1190 if (s_playObj) {
1191 s_playObj->halt();
1192 delete s_playObj;
1193 s_playObj = 0;
1196 #endif
1200 QString SoundContent::messageWhenOpenning(OpenMessage where)
1202 switch (where) {
1203 case OpenOne: return i18n("Opening sound...");
1204 case OpenSeveral: return i18n("Opening sounds...");
1205 case OpenOneWith: return i18n("Opening sound with...");
1206 case OpenSeveralWith: return i18n("Opening sounds with...");
1207 case OpenOneWithDialog: return i18n("Open sound with:");
1208 case OpenSeveralWithDialog: return i18n("Open sounds with:");
1209 default: return "";
1213 /** class LinkContent:
1216 LinkContent::LinkContent(Note *parent, const KURL &url, const QString &title, const QString &icon, bool autoTitle, bool autoIcon)
1217 : NoteContent(parent), m_http(0), m_httpBuff(0), m_previewJob(0)
1219 setLink(url, title, icon, autoTitle, autoIcon);
1221 LinkContent::~LinkContent()
1223 delete m_http;
1224 delete m_httpBuff;
1227 int LinkContent::setWidthAndGetHeight(int width)
1229 m_linkDisplay.setWidth(width);
1230 return m_linkDisplay.height();
1233 void LinkContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered)
1235 m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0);
1238 void LinkContent::saveToNode(QDomDocument &doc, QDomElement &content)
1240 content.setAttribute("title", title() );
1241 content.setAttribute("icon", icon() );
1242 content.setAttribute("autoTitle", (autoTitle() ? "true" : "false"));
1243 content.setAttribute("autoIcon", (autoIcon() ? "true" : "false"));
1244 QDomText textNode = doc.createTextNode(url().prettyURL());
1245 content.appendChild(textNode);
1249 void LinkContent::toolTipInfos(QStringList *keys, QStringList *values)
1251 keys->append(i18n("Target"));
1252 values->append(m_url.prettyURL());
1255 int LinkContent::zoneAt(const QPoint &pos)
1257 return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0);
1260 QRect LinkContent::zoneRect(int zone, const QPoint &/*pos*/)
1262 QRect linkRect = m_linkDisplay.iconButtonRect();
1264 if (zone == Note::Custom0)
1265 return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect()
1266 else if (zone == Note::Content)
1267 return linkRect;
1268 else
1269 return QRect();
1272 QString LinkContent::zoneTip(int zone)
1274 return (zone == Note::Custom0 ? i18n("Open this link") : QString());
1277 void LinkContent::setCursor(QWidget *widget, int zone)
1279 if (zone == Note::Custom0)
1280 widget->setCursor(Qt::PointingHandCursor);
1283 QString LinkContent::statusBarMessage(int zone)
1285 if (zone == Note::Custom0 || zone == Note::Content)
1286 return m_url.prettyURL();
1287 else
1288 return "";
1292 KURL LinkContent::urlToOpen(bool /*with*/)
1294 return NoteFactory::filteredURL(url());//KURIFilter::self()->filteredURI(url());
1297 QString LinkContent::messageWhenOpenning(OpenMessage where)
1299 if (url().isEmpty())
1300 return i18n("Link have no URL to open.");
1302 switch (where) {
1303 case OpenOne: return i18n("Opening link target...");
1304 case OpenSeveral: return i18n("Opening link targets...");
1305 case OpenOneWith: return i18n("Opening link target with...");
1306 case OpenSeveralWith: return i18n("Opening link targets with...");
1307 case OpenOneWithDialog: return i18n("Open link target with:");
1308 case OpenSeveralWithDialog: return i18n("Open link targets with:");
1309 default: return "";
1313 void LinkContent::setLink(const KURL &url, const QString &title, const QString &icon, bool autoTitle, bool autoIcon)
1315 m_autoTitle = autoTitle;
1316 m_autoIcon = autoIcon;
1317 m_url = NoteFactory::filteredURL(KURL(url));//KURIFilter::self()->filteredURI(url);
1318 m_title = (autoTitle ? NoteFactory::titleForURL(m_url) : title);
1319 m_icon = (autoIcon ? NoteFactory::iconForURL(m_url) : icon);
1321 LinkLook *look = LinkLook::lookForURL(m_url);
1322 if (look->previewEnabled())
1323 m_linkDisplay.setLink(m_title, m_icon, look, note()->font());
1324 else
1325 m_linkDisplay.setLink(m_title, m_icon, QPixmap(), look, note()->font());
1326 startFetchingUrlPreview();
1327 if(autoTitle)
1328 startFetchingLinkTitle();
1329 contentChanged(m_linkDisplay.minWidth());
1332 void LinkContent::linkLookChanged()
1334 fontChanged();
1337 void LinkContent::newPreview(const KFileItem*, const QPixmap &preview)
1339 LinkLook *linkLook = LinkLook::lookForURL(url());
1340 m_linkDisplay.setLink(title(), icon(), (linkLook->previewEnabled() ? preview : QPixmap()), linkLook, note()->font());
1341 contentChanged(m_linkDisplay.minWidth());
1344 void LinkContent::removePreview(const KFileItem*)
1346 newPreview(0, QPixmap());
1349 // QHttp slots for getting link title
1350 void LinkContent::httpReadyRead(const Q3HttpResponseHeader& )
1352 Q_ULONG bytesAvailable = m_http->bytesAvailable();
1353 if(bytesAvailable <= 0)
1354 return;
1356 char* buf = new char[bytesAvailable+1];
1358 Q_LONG bytes_read = m_http->readBlock(buf, bytesAvailable);
1359 if(bytes_read > 0) {
1361 // m_httpBuff will keep data if title is not found in initial read
1362 if(m_httpBuff == 0) {
1363 m_httpBuff = new QString(buf);
1365 else {
1366 (*m_httpBuff) += buf;
1369 // todo: this should probably strip odd html tags like &nbsp; etc
1370 QRegExp reg("<title>[\\s]*(&nbsp;)?([^<]+)[\\s]*</title>", false);
1371 reg.setMinimal(TRUE);
1372 int offset = 0;
1373 //std::cout << *m_httpBuff << " bytes: " << bytes_read << std::endl;
1374 if((offset = reg.search(*m_httpBuff)) >= 0) {
1375 m_title = reg.cap(2);
1376 m_autoTitle = false;
1377 setEdited();
1379 // refresh the title
1380 setLink(url(), title(), icon(), autoTitle(), autoIcon());
1382 // stop the http connection
1383 m_http->abort();
1385 delete m_httpBuff;
1386 m_httpBuff = 0;
1388 // Stop at 10k bytes
1389 else if(m_httpBuff->length() > 10000) {
1390 m_http->abort();
1391 delete m_httpBuff;
1392 m_httpBuff = 0;
1395 delete buf;
1397 void LinkContent::httpDone(bool)
1399 m_http->closeConnection();
1402 void LinkContent::startFetchingLinkTitle()
1404 if(this->url().protocol() == "http")
1406 // delete old m_http, for some reason it will not connect a second time...
1407 if(m_http != 0) {
1408 delete m_http;
1409 m_http = 0;
1411 if(m_http == 0) {
1412 m_http = new Q3Http(this);
1413 connect(m_http, SIGNAL(done(bool)), this, SLOT(httpDone(bool)));
1414 connect(m_http, SIGNAL(readyRead(const Q3HttpResponseHeader&)), this,
1415 SLOT(httpReadyRead(const Q3HttpResponseHeader&)));
1417 m_http->setHost(this->url().host(), this->url().port() == 0 ? 80: this->url().port());
1418 QString path = this->url().encodedPathAndQuery(1);
1419 if(path == "")
1420 path = "/";
1421 //std::cout << "path: " << path << std::endl;
1422 m_http->get(path);
1426 // Code dupicated from FileContent::startFetchingUrlPreview()
1427 void LinkContent::startFetchingUrlPreview()
1429 KURL url = this->url();
1430 LinkLook *linkLook = LinkLook::lookForURL(this->url());
1432 // delete m_previewJob;
1433 if (!url.isEmpty() && linkLook->previewSize() > 0) {
1434 KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url);
1435 KURL::List urlList;
1436 urlList.append(filteredUrl);
1437 m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize());
1438 connect( m_previewJob, SIGNAL(gotPreview(const KFileItem*, const QPixmap&)), this, SLOT(newPreview(const KFileItem*, const QPixmap&)) );
1439 connect( m_previewJob, SIGNAL(failed(const KFileItem*)), this, SLOT(removePreview(const KFileItem*)) );
1443 void LinkContent::exportToHTML(HTMLExporter *exporter, int indent)
1445 QString linkTitle = title();
1447 // TODO:
1448 // // Append address (useful for print version of the page/basket):
1449 // if (exportData.formatForImpression && (!autoTitle() && title() != NoteFactory::titleForURL(url().prettyURL()))) {
1450 // // The address is on a new line, unless title is empty (empty lines was replaced by &nbsp;):
1451 // if (linkTitle == " "/*"&nbsp;"*/)
1452 // linkTitle = url().prettyURL()/*""*/;
1453 // else
1454 // linkTitle = linkTitle + " <" + url().prettyURL() + ">"/*+ "<br>"*/;
1455 // //linkTitle += "<i>" + url().prettyURL() + "</i>";
1456 // }
1458 KURL linkURL;
1460 QFileInfo fInfo(url().path());
1461 // DEBUG_WIN << url().path()
1462 // << "IsFile:" + QString::number(fInfo.isFile())
1463 // << "IsDir:" + QString::number(fInfo.isDir());
1464 if (exportData.embedLinkedFiles && fInfo.isFile()) {
1465 // DEBUG_WIN << "Embed file";
1466 linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true);
1467 } else if (exportData.embedLinkedFolders && fInfo.isDir()) {
1468 // DEBUG_WIN << "Embed folder";
1469 linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true);
1470 } else {
1471 // DEBUG_WIN << "Embed LINK";
1473 linkURL = url();
1478 QString spaces;
1479 exporter->stream << m_linkDisplay.toHtml(exporter, linkURL, linkTitle).replace("\n", "\n" + spaces.fill(' ', indent + 1));
1482 /** class LauncherContent:
1485 LauncherContent::LauncherContent(Note *parent, const QString &fileName)
1486 : NoteContent(parent, fileName)
1488 basket()->addWatchedFile(fullPath());
1489 loadFromFile(/*lazyLoad=*/false);
1492 int LauncherContent::setWidthAndGetHeight(int width)
1494 m_linkDisplay.setWidth(width);
1495 return m_linkDisplay.height();
1498 void LauncherContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered)
1500 m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0);
1503 bool LauncherContent::loadFromFile(bool /*lazyLoad*/) // TODO: saveToFile() ?? Is it possible?
1505 DEBUG_WIN << "Loading LauncherContent From " + basket()->folderName() + fileName();
1506 KService service(fullPath());
1507 setLauncher(service.name(), service.icon(), service.exec());
1508 return true;
1512 void LauncherContent::toolTipInfos(QStringList *keys, QStringList *values)
1514 KService service(fullPath());
1516 QString exec = service.exec();
1517 if (service.terminal())
1518 exec = i18n("%1 <i>(run in terminal)</i>").arg(exec);
1520 if (!service.comment().isEmpty() && service.comment() != service.name()) {
1521 keys->append(i18n("Comment"));
1522 values->append(service.comment());
1525 keys->append(i18n("Command"));
1526 values->append(exec);
1529 int LauncherContent::zoneAt(const QPoint &pos)
1531 return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0);
1534 QRect LauncherContent::zoneRect(int zone, const QPoint &/*pos*/)
1536 QRect linkRect = m_linkDisplay.iconButtonRect();
1538 if (zone == Note::Custom0)
1539 return QRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect()
1540 else if (zone == Note::Content)
1541 return linkRect;
1542 else
1543 return QRect();
1546 QString LauncherContent::zoneTip(int zone)
1548 return (zone == Note::Custom0 ? i18n("Launch this application") : QString());
1551 void LauncherContent::setCursor(QWidget *widget, int zone)
1553 if (zone == Note::Custom0)
1554 widget->setCursor(Qt::PointingHandCursor);
1558 KURL LauncherContent::urlToOpen(bool with)
1560 if (KService(fullPath()).exec().isEmpty())
1561 return KURL();
1563 return (with ? KURL() : KURL(fullPath())); // Can open the appliation, but not with another application :-)
1566 QString LauncherContent::messageWhenOpenning(OpenMessage where)
1568 if (KService(fullPath()).exec().isEmpty())
1569 return i18n("The launcher have no command to run.");
1571 switch (where) {
1572 case OpenOne: return i18n("Launching application...");
1573 case OpenSeveral: return i18n("Launching applications...");
1574 case OpenOneWith:
1575 case OpenSeveralWith:
1576 case OpenOneWithDialog:
1577 case OpenSeveralWithDialog: // TODO: "Open this application with this file as parameter"?
1578 default: return "";
1582 void LauncherContent::setLauncher(const QString &name, const QString &icon, const QString &exec)
1584 m_name = name;
1585 m_icon = icon;
1586 m_exec = exec;
1588 m_linkDisplay.setLink(name, icon, LinkLook::launcherLook, note()->font());
1589 contentChanged(m_linkDisplay.minWidth());
1592 void LauncherContent::exportToHTML(HTMLExporter *exporter, int indent)
1594 QString spaces;
1595 QString fileName = exporter->copyFile(fullPath(), /*createIt=*/true);
1596 exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1));
1599 /** class ColorContent:
1602 const int ColorContent::RECT_MARGIN = 2;
1604 ColorContent::ColorContent(Note *parent, const QColor &color)
1605 : NoteContent(parent)
1607 setColor(color);
1610 int ColorContent::setWidthAndGetHeight(int /*width*/) // We do not need width because we can't word-break, and width is always >= minWidth()
1612 // FIXME: Duplicate from setColor():
1613 QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name());
1614 int rectHeight = (textRect.height() + 2)*3/2;
1615 return rectHeight;
1618 void ColorContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
1620 // FIXME: Duplicate from setColor():
1621 QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name());
1622 int rectHeight = (textRect.height() + 2)*3/2;
1623 int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers.
1625 // FIXME: Duplicate from CommonColorSelector::drawColorRect:
1626 // Fill:
1627 painter->fillRect(1, 1, rectWidth - 2, rectHeight - 2, color());
1628 // Stroke:
1629 QColor stroke = color().dark(125);
1630 painter->setPen(stroke);
1631 painter->drawLine(1, 0, rectWidth - 2, 0);
1632 painter->drawLine(0, 1, 0, rectHeight - 2);
1633 painter->drawLine(1, rectHeight - 1, rectWidth - 2, rectHeight - 1);
1634 painter->drawLine(rectWidth - 1, 1, rectWidth - 1, rectHeight - 2);
1635 // Round corners:
1636 painter->setPen(Tools::mixColor(color(), stroke));
1637 painter->drawPoint(1, 1);
1638 painter->drawPoint(1, rectHeight - 2);
1639 painter->drawPoint(rectWidth - 2, rectHeight - 2);
1640 painter->drawPoint(rectWidth - 2, 1);
1642 // Draw the text:
1643 painter->setFont(note()->font());
1644 painter->setPen(colorGroup.text());
1645 painter->drawText(rectWidth + RECT_MARGIN, 0, width - rectWidth - RECT_MARGIN, height, Qt::AlignAuto | Qt::AlignVCenter, color().name());
1648 void ColorContent::saveToNode(QDomDocument &doc, QDomElement &content)
1650 QDomText textNode = doc.createTextNode(color().name());
1651 content.appendChild(textNode);
1655 void ColorContent::toolTipInfos(QStringList *keys, QStringList *values)
1657 int hue, saturation, value;
1658 m_color.getHsv(hue, saturation, value);
1660 keys->append(i18n("RGB Colorspace: Red/Green/Blue", "RGB"));
1661 values->append(i18n("<i>Red</i>: %1, <i>Green</i>: %2, <i>Blue</i>: %3,").arg(QString::number(m_color.red()), QString::number(m_color.green()), QString::number(m_color.blue())));
1663 keys->append(i18n("HSV Colorspace: Hue/Saturation/Value", "HSV"));
1664 values->append(i18n("<i>Hue</i>: %1, <i>Saturation</i>: %2, <i>Value</i>: %3,").arg(QString::number(hue), QString::number(saturation), QString::number(value)));
1666 static QString cssColors[] = {
1667 "aqua", "00ffff",
1668 "black", "000000",
1669 "blue", "0000ff",
1670 "fuchsia", "ff00ff",
1671 "gray", "808080",
1672 "green", "008000",
1673 "lime", "00ff00",
1674 "maroon", "800000",
1675 "navy", "000080",
1676 "olive", "808000",
1677 "purple", "800080",
1678 "red", "ff0000",
1679 "silver", "c0c0c0",
1680 "teal", "008080",
1681 "white", "ffffff",
1682 "yellow", "ffff00"
1685 static QString cssExtendedColors[] = {
1686 "aliceblue", "f0f8ff",
1687 "antiquewhite", "faebd7",
1688 "aquamarine", "7fffd4",
1689 "azure", "f0ffff",
1690 "beige", "f5f5dc",
1691 "bisque", "ffe4c4",
1692 "blanchedalmond", "ffebcd",
1693 "blueviolet", "8a2be2",
1694 "brown", "a52a2a",
1695 "burlywood", "deb887",
1696 "cadetblue", "5f9ea0",
1697 "chartreuse", "7fff00",
1698 "chocolate", "d2691e",
1699 "coral", "ff7f50",
1700 "cornflowerblue", "6495ed",
1701 "cornsilk", "fff8dc",
1702 "crimson", "dc1436",
1703 "cyan", "00ffff",
1704 "darkblue", "00008b",
1705 "darkcyan", "008b8b",
1706 "darkgoldenrod", "b8860b",
1707 "darkgray", "a9a9a9",
1708 "darkgreen", "006400",
1709 "darkkhaki", "bdb76b",
1710 "darkmagenta", "8b008b",
1711 "darkolivegreen", "556b2f",
1712 "darkorange", "ff8c00",
1713 "darkorchid", "9932cc",
1714 "darkred", "8b0000",
1715 "darksalmon", "e9967a",
1716 "darkseagreen", "8fbc8f",
1717 "darkslateblue", "483d8b",
1718 "darkslategray", "2f4f4f",
1719 "darkturquoise", "00ced1",
1720 "darkviolet", "9400d3",
1721 "deeppink", "ff1493",
1722 "deepskyblue", "00bfff",
1723 "dimgray", "696969",
1724 "dodgerblue", "1e90ff",
1725 "firebrick", "b22222",
1726 "floralwhite", "fffaf0",
1727 "forestgreen", "228b22",
1728 "gainsboro", "dcdcdc",
1729 "ghostwhite", "f8f8ff",
1730 "gold", "ffd700",
1731 "goldenrod", "daa520",
1732 "greenyellow", "adff2f",
1733 "honeydew", "f0fff0",
1734 "hotpink", "ff69b4",
1735 "indianred", "cd5c5c",
1736 "indigo", "4b0082",
1737 "ivory", "fffff0",
1738 "khaki", "f0e68c",
1739 "lavender", "e6e6fa",
1740 "lavenderblush", "fff0f5",
1741 "lawngreen", "7cfc00",
1742 "lemonchiffon", "fffacd",
1743 "lightblue", "add8e6",
1744 "lightcoral", "f08080",
1745 "lightcyan", "e0ffff",
1746 "lightgoldenrodyellow", "fafad2",
1747 "lightgreen", "90ee90",
1748 "lightgrey", "d3d3d3",
1749 "lightpink", "ffb6c1",
1750 "lightsalmon", "ffa07a",
1751 "lightseagreen", "20b2aa",
1752 "lightskyblue", "87cefa",
1753 "lightslategray", "778899",
1754 "lightsteelblue", "b0c4de",
1755 "lightyellow", "ffffe0",
1756 "limegreen", "32cd32",
1757 "linen", "faf0e6",
1758 "magenta", "ff00ff",
1759 "mediumaquamarine", "66cdaa",
1760 "mediumblue", "0000cd",
1761 "mediumorchid", "ba55d3",
1762 "mediumpurple", "9370db",
1763 "mediumseagreen", "3cb371",
1764 "mediumslateblue", "7b68ee",
1765 "mediumspringgreen", "00fa9a",
1766 "mediumturquoise", "48d1cc",
1767 "mediumvioletred", "c71585",
1768 "midnightblue", "191970",
1769 "mintcream", "f5fffa",
1770 "mistyrose", "ffe4e1",
1771 "moccasin", "ffe4b5",
1772 "navajowhite", "ffdead",
1773 "oldlace", "fdf5e6",
1774 "olivedrab", "6b8e23",
1775 "orange", "ffa500",
1776 "orangered", "ff4500",
1777 "orchid", "da70d6",
1778 "palegoldenrod", "eee8aa",
1779 "palegreen", "98fb98",
1780 "paleturquoise", "afeeee",
1781 "palevioletred", "db7093",
1782 "papayawhip", "ffefd5",
1783 "peachpuff", "ffdab9",
1784 "peru", "cd853f",
1785 "pink", "ffc0cb",
1786 "plum", "dda0dd",
1787 "powderblue", "b0e0e6",
1788 "rosybrown", "bc8f8f",
1789 "royalblue", "4169e1",
1790 "saddlebrown", "8b4513",
1791 "salmon", "fa8072",
1792 "sandybrown", "f4a460",
1793 "seagreen", "2e8b57",
1794 "seashell", "fff5ee",
1795 "sienna", "a0522d",
1796 "skyblue", "87ceeb",
1797 "slateblue", "6a5acd",
1798 "slategray", "708090",
1799 "snow", "fffafa",
1800 "springgreen", "00ff7f",
1801 "steelblue", "4682b4",
1802 "tan", "d2b48c",
1803 "thistle", "d8bfd8",
1804 "tomato", "ff6347",
1805 "turquoise", "40e0d0",
1806 "violet", "ee82ee",
1807 "wheat", "f5deb3",
1808 "whitesmoke", "f5f5f5",
1809 "yellowgreen", "9acd32"
1812 QString colorHex = color().name().mid(1); // Take the hexadecimal name of the color, without the '#'.
1814 bool cssColorFound = false;
1815 for (int i = 0; i < 2*16; i += 2) {
1816 if (colorHex == cssColors[i+1]) {
1817 keys->append(i18n("CSS Color Name"));
1818 values->append(cssColors[i]);
1819 cssColorFound = true;
1820 break;
1824 if (!cssColorFound)
1825 for (int i = 0; i < 2*124; i += 2) {
1826 if (colorHex == cssExtendedColors[i+1]) {
1827 keys->append(i18n("CSS Extended Color Name"));
1828 values->append(cssExtendedColors[i]);
1829 break;
1833 keys->append(i18n("Is Web Color"));
1834 values->append(Tools::isWebColor(color()) ? i18n("Yes") : i18n("No"));
1838 void ColorContent::setColor(const QColor &color)
1840 m_color = color;
1842 QRect textRect = QFontMetrics(note()->font()).boundingRect(color.name());
1843 int rectHeight = (textRect.height() + 2)*3/2;
1844 int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers.
1845 contentChanged(rectWidth + RECT_MARGIN + textRect.width() + RECT_MARGIN); // The second RECT_MARGIN is because textRect.width() is too short. I done a bug? Can't figure out.
1848 void ColorContent::addAlternateDragObjects(KMultipleDrag *dragObject)
1850 dragObject->addDragObject( new Q3ColorDrag(color()) );
1852 // addDragObject(new KColorDrag( note->color(), 0 ));
1853 // addDragObject(new QTextDrag( note->color().name(), 0 ));
1855 /* // Creata and add the QDragObject:
1856 storedDrag = new QStoredDrag("application/x-color");
1857 storedDrag->setEncodedData(*array);
1858 dragObject->addDragObject(storedDrag);
1859 delete array;*/
1862 void ColorContent::exportToHTML(HTMLExporter *exporter, int /*indent*/)
1864 // FIXME: Duplicate from setColor(): TODO: rectSize()
1865 QRect textRect = QFontMetrics(note()->font()).boundingRect(color().name());
1866 int rectHeight = (textRect.height() + 2)*3/2;
1867 int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers.
1869 QString fileName = /*Tools::fileNameForNewFile(*/QString("color_%1.png").arg(color().name().lower().mid(1))/*, exportData.iconsFolderPath)*/;
1870 QString fullPath = exporter->iconsFolderPath + fileName;
1871 QPixmap colorIcon = KColorCombo2::colorRectPixmap(color(), /*isDefault=*/false, rectWidth, rectHeight);
1872 colorIcon.save(fullPath, "PNG");
1873 QString iconHtml = QString("<img src=\"%1\" width=\"%2\" height=\"%3\" alt=\"\">")
1874 .arg(exporter->iconsFolderName + fileName, QString::number(colorIcon.width()), QString::number(colorIcon.height()));
1876 exporter->stream << iconHtml + " " + color().name();
1881 /** class UnknownContent:
1884 const int UnknownContent::DECORATION_MARGIN = 2;
1886 UnknownContent::UnknownContent(Note *parent, const QString &fileName)
1887 : NoteContent(parent, fileName)
1889 basket()->addWatchedFile(fullPath());
1890 loadFromFile(/*lazyLoad=*/false);
1893 int UnknownContent::setWidthAndGetHeight(int width)
1895 width -= 1;
1896 QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, width, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes);
1897 return DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN;
1900 // TODO: Move this function from note.cpp to class Tools:
1901 extern void drawGradient( QPainter *p, const QColor &colorTop, const QColor & colorBottom,
1902 int x, int y, int w, int h,
1903 bool sunken, bool horz, bool flat ); /*const*/
1905 void UnknownContent::paint(QPainter *painter, int width, int height, const QColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/)
1907 width -= 1;
1908 painter->setPen(colorGroup.text());
1910 // FIXME: Duplicate from ColorContent::paint() and CommonColorSelector::drawColorRect:
1911 // Fill with gradient:
1912 drawGradient(painter, colorGroup.background(), colorGroup.background().dark(110), 1, 1, width - 2, height - 2, /*sunken=*/false, /*horz=*/true, /*flat=*/false);
1913 // Stroke:
1914 QColor stroke = Tools::mixColor(colorGroup.background(), colorGroup.text());
1915 painter->setPen(stroke);
1916 painter->drawLine(1, 0, width - 2, 0);
1917 painter->drawLine(0, 1, 0, height - 2);
1918 painter->drawLine(1, height - 1, width - 2, height - 1);
1919 painter->drawLine(width - 1, 1, width - 1, height - 2);
1920 // Round corners:
1921 painter->setPen(Tools::mixColor(colorGroup.background(), stroke));
1922 painter->drawPoint(1, 1);
1923 painter->drawPoint(1, height - 2);
1924 painter->drawPoint(width - 2, height - 2);
1925 painter->drawPoint(width - 2, 1);
1927 painter->setPen(colorGroup.text());
1928 painter->drawText(DECORATION_MARGIN, DECORATION_MARGIN, width - 2*DECORATION_MARGIN, height - 2*DECORATION_MARGIN,
1929 Qt::AlignAuto | Qt::AlignVCenter | Qt::WordBreak, m_mimeTypes);
1932 bool UnknownContent::loadFromFile(bool /*lazyLoad*/)
1934 DEBUG_WIN << "Loading UnknownContent From " + basket()->folderName() + fileName();
1935 QFile file(fullPath());
1936 if (file.open(QIODevice::ReadOnly)) {
1937 QDataStream stream(&file);
1938 QString line;
1939 m_mimeTypes = "";
1940 // Get the MIME-types names:
1941 do {
1942 if (!stream.atEnd()) {
1943 stream >> line;
1944 if (!line.isEmpty()) {
1945 if (m_mimeTypes.isEmpty())
1946 m_mimeTypes += line;
1947 else
1948 m_mimeTypes += QString("\n") + line;
1951 } while (!line.isEmpty() && !stream.atEnd());
1952 file.close();
1955 QRect textRect = QFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, Qt::AlignAuto | Qt::AlignTop | Qt::WordBreak, m_mimeTypes);
1956 contentChanged(DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN + 1);
1957 return true;
1960 void UnknownContent::addAlternateDragObjects(KMultipleDrag *dragObject)
1962 QFile file(fullPath());
1963 if (file.open(QIODevice::ReadOnly)) {
1964 QDataStream stream(&file);
1965 // Get the MIME types names:
1966 Q3ValueList<QString> mimes;
1967 QString line;
1968 do {
1969 if (!stream.atEnd()) {
1970 stream >> line;
1971 if (!line.isEmpty())
1972 mimes.append(line);
1974 } while (!line.isEmpty() && !stream.atEnd());
1975 // Add the streams:
1976 Q_UINT64 size; // TODO: It was Q_UINT32 in version 0.5.0 !
1977 QByteArray *array;
1978 Q3StoredDrag *storedDrag;
1979 for (uint i = 0; i < mimes.count(); ++i) {
1980 // Get the size:
1981 stream >> size;
1982 // Allocate memory to retreive size bytes and store them:
1983 array = new QByteArray(size);
1984 stream.readRawBytes(array->data(), size);
1985 // Creata and add the QDragObject:
1986 storedDrag = new Q3StoredDrag(*(mimes.at(i)));
1987 storedDrag->setEncodedData(*array);
1988 dragObject->addDragObject(storedDrag);
1989 delete array; // FIXME: Should we?
1991 file.close();
1995 void UnknownContent::exportToHTML(HTMLExporter *exporter, int indent)
1997 QString spaces;
1998 exporter->stream << "<div class=\"unknown\">" << mimeTypes().replace("\n", "\n" + spaces.fill(' ', indent + 1 + 1)) << "</div>";
2004 void NoteFactory__loadNode(const QDomElement &content, const QString &lowerTypeName, Note *parent, bool lazyLoad)
2006 if (lowerTypeName == "text") new TextContent( parent, content.text(), lazyLoad );
2007 else if (lowerTypeName == "html") new HtmlContent( parent, content.text(), lazyLoad );
2008 else if (lowerTypeName == "image") new ImageContent( parent, content.text(), lazyLoad );
2009 else if (lowerTypeName == "animation") new AnimationContent( parent, content.text(), lazyLoad );
2010 else if (lowerTypeName == "sound") new SoundContent( parent, content.text() );
2011 else if (lowerTypeName == "file") new FileContent( parent, content.text() );
2012 else if (lowerTypeName == "link") {
2013 bool autoTitle = content.attribute("title") == content.text();
2014 bool autoIcon = content.attribute("icon") == NoteFactory::iconForURL(KURL(content.text()));
2015 autoTitle = XMLWork::trueOrFalse( content.attribute("autoTitle"), autoTitle);
2016 autoIcon = XMLWork::trueOrFalse( content.attribute("autoIcon"), autoIcon );
2017 new LinkContent( parent, KURL(content.text()), content.attribute("title"), content.attribute("icon"), autoTitle, autoIcon );
2018 } else if (lowerTypeName == "launcher") new LauncherContent( parent, content.text() );
2019 else if (lowerTypeName == "color") new ColorContent( parent, QColor(content.text()) );
2020 else if (lowerTypeName == "unknown") new UnknownContent( parent, content.text() );
2023 #include "notecontent.moc"