/*************************************************************************** * Copyright (C) 2003 by S�astien Laot * * slaout@linux62.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include //#include #include #include #include #include #include "notecontent.h" #include "note.h" #include "noteedit.h" #include "tag.h" #include "basket.h" #include "filter.h" #include "xmlwork.h" #include "tools.h" #include "notefactory.h" #include "linklabel.h" #include "global.h" #include "settings.h" #include "focusedwidgets.h" #include "debugwindow.h" #include "kcolorcombo2.h" #include "htmlexporter.h" #include "config.h" #ifndef WITHOUT_ARTS #include #include #include #include #endif /** class NoteContent: */ const int NoteContent::FEEDBACK_DARKING = 105; NoteContent::NoteContent(Note *parent, const TQString &fileName) : m_note(parent) { parent->setContent(this); setFileName(fileName); } void NoteContent::saveToNode(TQDomDocument &doc, TQDomElement &content) { if (useFile()) { TQDomText textNode = doc.createTextNode(fileName()); content.appendChild(textNode); } } TQRect NoteContent::zoneRect(int zone, const TQPoint &/*pos*/) { if (zone == Note::Content) return TQRect(0, 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() else return TQRect(); } KURL NoteContent::urlToOpen(bool /*with*/) { return (useFile() ? KURL(fullPath()) : KURL()); } void NoteContent::setFileName(const TQString &fileName) { m_fileName = fileName; } bool NoteContent::trySetFileName(const TQString &fileName) { if (useFile() && fileName != m_fileName) { TQString newFileName = Tools::fileNameForNewFile(fileName, basket()->fullPath()); TQDir dir; dir.rename(fullPath(), basket()->fullPathForFileName(newFileName)); return true; } return false; // !useFile() or unsuccesful rename } TQString NoteContent::fullPath() { if (note() && useFile()) return note()->fullPath(); else return ""; } void NoteContent::contentChanged(int newMinWidth) { m_minWidth = newMinWidth; if (note()) { // note()->unbufferize(); note()->requestRetqlayout(); // TODO: It should re-set the width! m_width = 0 ? contentChanged: setWidth, geteight, if size havent changed, only repaint and not retqlayout } } Basket* NoteContent::basket() { if (note()) return note()->basket(); else return 0; } void NoteContent::setEdited() { note()->setLastModificationDate(TQDateTime::currentDateTime()); basket()->save(); } /** All the Content Classes: */ NoteType::Id TextContent::type() { return NoteType::Text; } NoteType::Id HtmlContent::type() { return NoteType::Html; } NoteType::Id ImageContent::type() { return NoteType::Image; } NoteType::Id AnimationContent::type() { return NoteType::Animation; } NoteType::Id SoundContent::type() { return NoteType::Sound; } NoteType::Id FileContent::type() { return NoteType::File; } NoteType::Id LinkContent::type() { return NoteType::Link; } NoteType::Id LauncherContent::type() { return NoteType::Launcher; } NoteType::Id ColorContent::type() { return NoteType::Color; } NoteType::Id UnknownContent::type() { return NoteType::Unknown; } TQString TextContent::typeName() { return i18n("Plain Text"); } TQString HtmlContent::typeName() { return i18n("Text"); } TQString ImageContent::typeName() { return i18n("Image"); } TQString AnimationContent::typeName() { return i18n("Animation"); } TQString SoundContent::typeName() { return i18n("Sound"); } TQString FileContent::typeName() { return i18n("File"); } TQString LinkContent::typeName() { return i18n("Link"); } TQString LauncherContent::typeName() { return i18n("Launcher"); } TQString ColorContent::typeName() { return i18n("Color"); } TQString UnknownContent::typeName() { return i18n("Unknown"); } TQString TextContent::lowerTypeName() { return "text"; } TQString HtmlContent::lowerTypeName() { return "html"; } TQString ImageContent::lowerTypeName() { return "image"; } TQString AnimationContent::lowerTypeName() { return "animation"; } TQString SoundContent::lowerTypeName() { return "sound"; } TQString FileContent::lowerTypeName() { return "file"; } TQString LinkContent::lowerTypeName() { return "link"; } TQString LauncherContent::lowerTypeName() { return "launcher"; } TQString ColorContent::lowerTypeName() { return "color"; } TQString UnknownContent::lowerTypeName() { return "unknown"; } TQString NoteContent::toText(const TQString &cuttedFullPath) { return (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } TQString TextContent::toText(const TQString &/*cuttedFullPath*/) { return text(); } TQString HtmlContent::toText(const TQString &/*cuttedFullPath*/) { return Tools::htmlToText(html()); } TQString LinkContent::toText(const TQString &/*cuttedFullPath*/) { if (autoTitle()) return url().prettyURL(); else if (title().isEmpty() && url().isEmpty()) return ""; else if (url().isEmpty()) return title(); else if (title().isEmpty()) return url().prettyURL(); else return TQString("%1 <%2>").arg(title(), url().prettyURL()); } TQString ColorContent::toText(const TQString &/*cuttedFullPath*/) { return color().name(); } TQString UnknownContent::toText(const TQString &/*cuttedFullPath*/) { return ""; } // TODO: If imageName.isEmpty() return fullPath() because it's for external use, else return fileName() because it's to display in a tooltip TQString TextContent::toHtml(const TQString &/*imageName*/, const TQString &/*cuttedFullPath*/) { return Tools::textToHTMLWithoutP(text()); } TQString HtmlContent::toHtml(const TQString &/*imageName*/, const TQString &/*cuttedFullPath*/) { return Tools::htmlToParagraph(html()); } TQString ImageContent::toHtml(const TQString &/*imageName*/, const TQString &cuttedFullPath) { return TQString("").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } TQString AnimationContent::toHtml(const TQString &/*imageName*/, const TQString &cuttedFullPath) { return TQString("").arg(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } TQString SoundContent::toHtml(const TQString &/*imageName*/, const TQString &cuttedFullPath) { return TQString("%2").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon? TQString FileContent::toHtml(const TQString &/*imageName*/, const TQString &cuttedFullPath) { return TQString("%2").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), fileName()); } // With the icon? TQString LinkContent::toHtml(const TQString &/*imageName*/, const TQString &/*cuttedFullPath*/) { return TQString("%2").arg(url().prettyURL(), title()); } // With the icon? TQString LauncherContent::toHtml(const TQString &/*imageName*/, const TQString &cuttedFullPath) { return TQString("%2").arg((cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath), name()); } // With the icon? TQString ColorContent::toHtml(const TQString &/*imageName*/, const TQString &/*cuttedFullPath*/) { return TQString("%2").arg(color().name(), color().name()); } TQString UnknownContent::toHtml(const TQString &/*imageName*/, const TQString &/*cuttedFullPath*/) { return ""; } TQPixmap ImageContent::toPixmap() { return pixmap(); } TQPixmap AnimationContent::toPixmap() { return movie().framePixmap(); } void NoteContent::toLink(KURL *url, TQString *title, const TQString &cuttedFullPath) { if (useFile()) { *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); *title = (cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); } else { *url = KURL(); *title = TQString(); } } void LinkContent::toLink(KURL *url, TQString *title, const TQString &/*cuttedFullPath*/) { *url = this->url(); *title = this->title(); } void LauncherContent::toLink(KURL *url, TQString *title, const TQString &cuttedFullPath) { *url = KURL(cuttedFullPath.isEmpty() ? fullPath() : cuttedFullPath); *title = name(); } void UnknownContent::toLink(KURL *url, TQString *title, const TQString &/*cuttedFullPath*/) { *url = KURL(); *title = TQString(); } bool TextContent::useFile() { return true; } bool HtmlContent::useFile() { return true; } bool ImageContent::useFile() { return true; } bool AnimationContent::useFile() { return true; } bool SoundContent::useFile() { return true; } bool FileContent::useFile() { return true; } bool LinkContent::useFile() { return false; } bool LauncherContent::useFile() { return true; } bool ColorContent::useFile() { return false; } bool UnknownContent::useFile() { return true; } bool TextContent::canBeSavedAs() { return true; } bool HtmlContent::canBeSavedAs() { return true; } bool ImageContent::canBeSavedAs() { return true; } bool AnimationContent::canBeSavedAs() { return true; } bool SoundContent::canBeSavedAs() { return true; } bool FileContent::canBeSavedAs() { return true; } bool LinkContent::canBeSavedAs() { return true; } bool LauncherContent::canBeSavedAs() { return true; } bool ColorContent::canBeSavedAs() { return false; } bool UnknownContent::canBeSavedAs() { return false; } TQString TextContent::saveAsFilters() { return "text/plain"; } TQString HtmlContent::saveAsFilters() { return "text/html"; } TQString ImageContent::saveAsFilters() { return "image/png"; } // TODO: Offer more types TQString AnimationContent::saveAsFilters() { return "image/gif"; } // TODO: MNG... TQString SoundContent::saveAsFilters() { return "audio/x-mp3"; } // TODO: OGG... TQString FileContent::saveAsFilters() { return "*"; } // TODO: Get MIME type of the url target TQString LinkContent::saveAsFilters() { return "*"; } // TODO: idem File + If isDir(): return TQString LauncherContent::saveAsFilters() { return "application/x-desktop"; } TQString ColorContent::saveAsFilters() { return ""; } TQString UnknownContent::saveAsFilters() { return ""; } bool TextContent::match(const FilterData &data) { return (text().find(data.string, /*index=*/0, /*cs=*/false) != -1); } bool HtmlContent::match(const FilterData &data) { return (m_textEquivalent/*toText("")*/.find(data.string, /*index=*/0, /*cs=*/false) != -1); } //OPTIM_FILTER bool ImageContent::match(const FilterData &/*data*/) { return false; } bool AnimationContent::match(const FilterData &/*data*/) { return false; } bool SoundContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); } bool FileContent::match(const FilterData &data) { return (fileName().find(data.string, /*index=*/0, /*cs=*/false) != -1); } bool LinkContent::match(const FilterData &data) { return (title().find(data.string, 0, false) != -1 || url().prettyURL().find(data.string, 0, false) != -1); } bool LauncherContent::match(const FilterData &data) { return (exec().find(data.string, 0, false) != -1 || name().find(data.string, 0, false) != -1); } bool ColorContent::match(const FilterData &data) { return (TQString(color().name()).find(data.string, /*index=*/0, /*cs=*/false) != -1); } bool UnknownContent::match(const FilterData &data) { return (mimeTypes().find(data.string, /*index=*/0, /*cs=*/false) != -1); } TQString TextContent::editToolTipText() { return i18n("Edit this plain text"); } TQString HtmlContent::editToolTipText() { return i18n("Edit this text"); } TQString ImageContent::editToolTipText() { return i18n("Edit this image"); } TQString AnimationContent::editToolTipText() { return i18n("Edit this animation"); } TQString SoundContent::editToolTipText() { return i18n("Edit the file name of this sound"); } TQString FileContent::editToolTipText() { return i18n("Edit the name of this file"); } TQString LinkContent::editToolTipText() { return i18n("Edit this link"); } TQString LauncherContent::editToolTipText() { return i18n("Edit this launcher"); } TQString ColorContent::editToolTipText() { return i18n("Edit this color"); } TQString UnknownContent::editToolTipText() { return i18n("Edit this unknown object"); } TQString TextContent::cssClass() { return ""; } TQString HtmlContent::cssClass() { return ""; } TQString ImageContent::cssClass() { return ""; } TQString AnimationContent::cssClass() { return ""; } TQString SoundContent::cssClass() { return "sound"; } TQString FileContent::cssClass() { return "file"; } TQString LinkContent::cssClass() { return (LinkLook::lookForURL(m_url) == LinkLook::localLinkLook ? "local" : "network"); } TQString LauncherContent::cssClass() { return "launcher"; } TQString ColorContent::cssClass() { return "" ; } TQString UnknownContent::cssClass() { return ""; } void TextContent::fontChanged() { setText(text()); } void HtmlContent::fontChanged() { setHtml(html()); } void ImageContent::fontChanged() { setPixmap(pixmap()); } void AnimationContent::fontChanged() { setMovie(movie()); } void FileContent::fontChanged() { setFileName(fileName()); } void LinkContent::fontChanged() { setLink(url(), title(), icon(), autoTitle(), autoIcon()); } void LauncherContent::fontChanged() { setLauncher(name(), icon(), exec()); } void ColorContent::fontChanged() { setColor(color()); } void UnknownContent::fontChanged() { loadFromFile(/*lazyLoad=*/false); } // TODO: Optimize: setMimeTypes() //TQString TextContent::customOpenCommand() { return (Settings::isTextUseProg() && ! Settings::textProg().isEmpty() ? Settings::textProg() : TQString()); } TQString HtmlContent::customOpenCommand() { return (Settings::isHtmlUseProg() && ! Settings::htmlProg().isEmpty() ? Settings::htmlProg() : TQString()); } TQString ImageContent::customOpenCommand() { return (Settings::isImageUseProg() && ! Settings::imageProg().isEmpty() ? Settings::imageProg() : TQString()); } TQString AnimationContent::customOpenCommand() { return (Settings::isAnimationUseProg() && ! Settings::animationProg().isEmpty() ? Settings::animationProg() : TQString()); } TQString SoundContent::customOpenCommand() { return (Settings::isSoundUseProg() && ! Settings::soundProg().isEmpty() ? Settings::soundProg() : TQString()); } void LinkContent::serialize(TQDataStream &stream) { stream << url() << title() << icon() << (TQ_UINT64)autoTitle() << (TQ_UINT64)autoIcon(); } void ColorContent::serialize(TQDataStream &stream) { stream << color(); } TQPixmap TextContent::feedbackPixmap(int width, int height) { TQRect textRect = TQFontMetrics(note()->font()).boundingRect(0, 0, width, height, TQt::AlignAuto | TQt::AlignTop | TQt::WordBreak, text()); TQPixmap pixmap( TQMIN(width, textRect.width()), TQMIN(height, textRect.height()) ); pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPainter painter(&pixmap); painter.setPen(note()->textColor()); painter.setFont(note()->font()); painter.drawText(0, 0, pixmap.width(), pixmap.height(), TQt::AlignAuto | TQt::AlignTop | TQt::WordBreak, text()); painter.end(); return pixmap; } TQPixmap HtmlContent::feedbackPixmap(int width, int height) { TQSimpleRichText richText(html(), note()->font()); richText.setWidth(width); TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPixmap pixmap( TQMIN(width, richText.widthUsed()), TQMIN(height, richText.height()) ); pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPainter painter(&pixmap); painter.setPen(note()->textColor()); richText.draw(&painter, 0, 0, TQRect(0, 0, pixmap.width(), pixmap.height()), colorGroup); painter.end(); return pixmap; } TQPixmap ImageContent::feedbackPixmap(int width, int height) { if (width >= m_pixmap.width() && height >= m_pixmap.height()) { // Full size if (m_pixmap.hasAlpha()) { TQPixmap opaque(m_pixmap.width(), m_pixmap.height()); opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPainter painter(&opaque); painter.drawPixmap(0, 0, m_pixmap); painter.end(); return opaque; } else return m_pixmap; } else { // Scalled down TQImage imageToScale = m_pixmap.convertToImage(); TQPixmap pmScaled; pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, TQ_ScaleMin)); if (pmScaled.hasAlpha()) { TQPixmap opaque(pmScaled.width(), pmScaled.height()); opaque.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPainter painter(&opaque); painter.drawPixmap(0, 0, pmScaled); painter.end(); return opaque; } else return pmScaled; } } TQPixmap AnimationContent::feedbackPixmap(int width, int height) { TQPixmap pixmap = m_movie.framePixmap(); if (width >= pixmap.width() && height >= pixmap.height()) // Full size return pixmap; else { // Scalled down TQImage imageToScale = pixmap.convertToImage(); TQPixmap pmScaled; pmScaled.convertFromImage(imageToScale./*smoothScale*/scale(width, height, TQ_ScaleMin)); return pmScaled; } } TQPixmap LinkContent::feedbackPixmap(int width, int height) { TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); } TQPixmap ColorContent::feedbackPixmap(int width, int height) { // TODO: Duplicate code: make a rect() method! TQRect textRect = TQFontMetrics(note()->font()).boundingRect(color().name()); int rectHeight = (textRect.height() + 2)*3/2; int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPixmap pixmap( TQMIN(width, rectWidth + RECT_MARGIN + textRect.width() + RECT_MARGIN), TQMIN(height, rectHeight) ); pixmap.fill(note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPainter painter(&pixmap); paint(&painter, pixmap.width(), pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters. painter.end(); return pixmap; } TQPixmap FileContent::feedbackPixmap(int width, int height) { TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); } TQPixmap LauncherContent::feedbackPixmap(int width, int height) { TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); return m_linkDisplay.feedbackPixmap(width, height, colorGroup, /*isDefaultColor=*/note()->textColor() == basket()->textColor()); } TQPixmap UnknownContent::feedbackPixmap(int width, int height) { TQRect textRect = TQFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, TQt::AlignAuto | TQt::AlignTop | TQt::WordBreak, m_mimeTypes); TQColorGroup colorGroup(basket()->colorGroup()); colorGroup.setColor(TQColorGroup::Text, note()->textColor()); colorGroup.setColor(TQColorGroup::Background, note()->backgroundColor().dark(FEEDBACK_DARKING)); TQPixmap pixmap( TQMIN(width, DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN), TQMIN(height, DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN) ); TQPainter painter(&pixmap); paint(&painter, pixmap.width() + 1, pixmap.height(), colorGroup, false, false, false); // We don't care of the three last boolean parameters. painter.setPen(note()->backgroundColor().dark(FEEDBACK_DARKING)); painter.drawPoint(0, 0); painter.drawPoint(pixmap.width() - 1, 0); painter.drawPoint(0, pixmap.height() - 1); painter.drawPoint(pixmap.width() - 1, pixmap.height() - 1); painter.end(); return pixmap; } /** class TextContent: */ TextContent::TextContent(Note *parent, const TQString &fileName, bool lazyLoad) : NoteContent(parent, fileName), m_simpleRichText(0) { basket()->addWatchedFile(fullPath()); loadFromFile(lazyLoad); } TextContent::~TextContent() { delete m_simpleRichText; } int TextContent::setWidthAndGetHeight(int width) { if (m_simpleRichText) { width -= 1; m_simpleRichText->setWidth(width); return m_simpleRichText->height(); } else return 10; // Lazy loaded } void TextContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { if (m_simpleRichText) { width -= 1; m_simpleRichText->draw(painter, 0, 0, TQRect(0, 0, width, height), colorGroup); } } bool TextContent::loadFromFile(bool lazyLoad) { DEBUG_WIN << "Loading TextContent From " + basket()->folderName() + fileName(); TQString content; bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true); if (success) setText(content, lazyLoad); else { std::cout << "FAILED TO LOAD TextContent: " << fullPath() << std::endl; setText("", lazyLoad); if (!TQFile::exists(fullPath())) saveToFile(); // Reserve the fileName so no new note will have the same name! } return success; } bool TextContent::finishLazyLoad() { int width = (m_simpleRichText ? m_simpleRichText->width() : 1); delete m_simpleRichText; TQString html = "" + Tools::tagURLs(Tools::textToHTML(m_text)); // Don't collapse multiple spaces! m_simpleRichText = new TQSimpleRichText(html, note()->font()); m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width int minWidth = m_simpleRichText->widthUsed(); m_simpleRichText->setWidth(width); contentChanged(minWidth + 1); return true; } bool TextContent::saveToFile() { return basket()->saveToFile(fullPath(), text(), /*isLocalEncoding=*/true); } TQString TextContent::linkAt(const TQPoint &pos) { if (m_simpleRichText) return m_simpleRichText->anchorAt(pos); else return ""; // Lazy loaded } TQString TextContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening plain text..."); case OpenSeveral: return i18n("Opening plain texts..."); case OpenOneWith: return i18n("Opening plain text with..."); case OpenSeveralWith: return i18n("Opening plain texts with..."); case OpenOneWithDialog: return i18n("Open plain text with:"); case OpenSeveralWithDialog: return i18n("Open plain texts with:"); default: return ""; } } void TextContent::setText(const TQString &text, bool lazyLoad) { m_text = text; if (!lazyLoad) finishLazyLoad(); else contentChanged(10); } void TextContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString spaces; TQString html = "" + Tools::tagURLs(Tools::textToHTMLWithoutP(text().replace("\t", " "))); // Don't collapse multiple spaces! exporter->stream << html.replace(" ", "  ").replace("\n", "\n" + spaces.fill(' ', indent + 1)); } /** class HtmlContent: */ HtmlContent::HtmlContent(Note *parent, const TQString &fileName, bool lazyLoad) : NoteContent(parent, fileName), m_simpleRichText(0) { basket()->addWatchedFile(fullPath()); loadFromFile(lazyLoad); } HtmlContent::~HtmlContent() { delete m_simpleRichText; } int HtmlContent::setWidthAndGetHeight(int width) { if (m_simpleRichText) { width -= 1; m_simpleRichText->setWidth(width); return m_simpleRichText->height(); } else return 10; // Lazy loaded } void HtmlContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { if (m_simpleRichText) { width -= 1; m_simpleRichText->draw(painter, 0, 0, TQRect(0, 0, width, height), colorGroup); } } bool HtmlContent::loadFromFile(bool lazyLoad) { DEBUG_WIN << "Loading HtmlContent From " + basket()->folderName() + fileName(); TQString content; bool success = basket()->loadFromFile(fullPath(), &content, /*isLocalEncoding=*/true); if (success) setHtml(content, lazyLoad); else { std::cout << "FAILED TO LOAD HtmlContent: " << fullPath() << std::endl; setHtml("", lazyLoad); if (!TQFile::exists(fullPath())) saveToFile(); // Reserve the fileName so no new note will have the same name! } return success; } bool HtmlContent::finishLazyLoad() { int width = (m_simpleRichText ? m_simpleRichText->width() : 1); delete m_simpleRichText; m_simpleRichText = new TQSimpleRichText(Tools::tagURLs(m_html), note()->font()); m_simpleRichText->setWidth(1); // We put a width of 1 pixel, so usedWidth() is egual to the minimum width int minWidth = m_simpleRichText->widthUsed(); m_simpleRichText->setWidth(width); contentChanged(minWidth + 1); return true; } bool HtmlContent::saveToFile() { return basket()->saveToFile(fullPath(), html(), /*isLocalEncoding=*/true); } TQString HtmlContent::linkAt(const TQPoint &pos) { if (m_simpleRichText) return m_simpleRichText->anchorAt(pos); else return ""; // Lazy loaded } TQString HtmlContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening text..."); case OpenSeveral: return i18n("Opening texts..."); case OpenOneWith: return i18n("Opening text with..."); case OpenSeveralWith: return i18n("Opening texts with..."); case OpenOneWithDialog: return i18n("Open text with:"); case OpenSeveralWithDialog: return i18n("Open texts with:"); default: return ""; } } void HtmlContent::setHtml(const TQString &html, bool lazyLoad) { m_html = html; m_textEquivalent = toText(""); //OPTIM_FILTER if (!lazyLoad) finishLazyLoad(); else contentChanged(10); } void HtmlContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString spaces; exporter->stream << Tools::htmlToParagraph(Tools::tagURLs(html().replace("\t", " "))) .replace(" ", "  ") .replace("\n", "\n" + spaces.fill(' ', indent + 1)); } /** class ImageContent: */ ImageContent::ImageContent(Note *parent, const TQString &fileName, bool lazyLoad) : NoteContent(parent, fileName), m_format(0) { basket()->addWatchedFile(fullPath()); loadFromFile(lazyLoad); } int ImageContent::setWidthAndGetHeight(int width) { width -= 1; // Don't store width: we will get it on paint! if (width >= m_pixmap.width()) // Full size return m_pixmap.height(); else { // Scalled down double height = m_pixmap.height() * (double)width / m_pixmap.width(); return int((double)(int)height <= (height - 0.5) ? height + 1 : height); } } void ImageContent::paint(TQPainter *painter, int width, int /*height*/, const TQColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { width -= 1; // KPixmap pixmap = m_pixmap; // if (note()->isSelected()) // pixmap = KPixmapEffect::selectedPixmap(m_pixmap, KGlobalSettings::highlightColor()); if (width >= m_pixmap.width()) // Full size painter->drawPixmap(0, 0, m_pixmap); else { // Scalled down double scale = ((double)width) / m_pixmap.width(); painter->scale(scale, scale); painter->drawPixmap(0, 0, m_pixmap); // TODO: Smooth !!! } } bool ImageContent::loadFromFile(bool lazyLoad) { if (lazyLoad) return true; else return finishLazyLoad(); } bool ImageContent::finishLazyLoad() { DEBUG_WIN << "Loading ImageContent From " + basket()->folderName() + fileName(); TQByteArray content; if (basket()->loadFromFile(fullPath(), &content)) { TQBuffer buffer(content); buffer.open(IO_ReadOnly); m_format = (char* /* from const char* */)TQImageIO::imageFormat(TQT_TQIODEVICE(&buffer)); // See TQImageIO to know what formats can be supported. buffer.close(); if (m_format) { m_pixmap.loadFromData(content); setPixmap(m_pixmap); return true; } } std::cout << "FAILED TO LOAD ImageContent: " << fullPath() << std::endl; m_format = (char*)"PNG"; // If the image is set later, it should be saved without destruction, so we use PNG by default. m_pixmap.resize(1, 1); // Create a 1x1 pixels image instead of an undefined one. m_pixmap.fill(); m_pixmap.setMask(m_pixmap.createHeuristicMask()); setPixmap(m_pixmap); if (!TQFile::exists(fullPath())) saveToFile(); // Reserve the fileName so no new note will have the same name! return false; } bool ImageContent::saveToFile() { TQByteArray ba; TQBuffer buffer(ba); buffer.open(IO_WriteOnly); m_pixmap.save(&buffer, m_format); return basket()->saveToFile(fullPath(), ba); } void ImageContent::toolTipInfos(TQStringList *keys, TQStringList *values) { keys->append(i18n("Size")); values->append(i18n("%1 by %2 pixels").arg(TQString::number(m_pixmap.width()), TQString::number(m_pixmap.height()))); } TQString ImageContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening image..."); case OpenSeveral: return i18n("Opening images..."); case OpenOneWith: return i18n("Opening image with..."); case OpenSeveralWith: return i18n("Opening images with..."); case OpenOneWithDialog: return i18n("Open image with:"); case OpenSeveralWithDialog: return i18n("Open images with:"); default: return ""; } } void ImageContent::setPixmap(const TQPixmap &pixmap) { m_pixmap = pixmap; // Since it's scalled, the height is always greater or equal to the size of the tag emblems (16) contentChanged(16 + 1); // TODO: always good? I don't think... } void ImageContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) { int width = m_pixmap.width(); int height = m_pixmap.height(); int contentWidth = note()->width() - note()->contentX() - 1 - Note::NOTE_MARGIN; TQString imageName = exporter->copyFile(fullPath(), /*createIt=*/true); if (contentWidth <= m_pixmap.width()) { // Scalled down double scale = ((double)contentWidth) / m_pixmap.width(); width = (int)(m_pixmap.width() * scale); height = (int)(m_pixmap.height() * scale); exporter->stream << "dataFolderName << imageName << "\" title=\"" << i18n("Click for full size view") << "\">"; } exporter->stream << "dataFolderName << imageName << "\" width=\"" << width << "\" height=\"" << height << "\" alt=\"\">"; if (contentWidth <= m_pixmap.width()) // Scalled down exporter->stream << ""; } /** class AnimationContent: */ int AnimationContent::INVALID_STATUS = -100; AnimationContent::AnimationContent(Note *parent, const TQString &fileName, bool lazyLoad) : NoteContent(parent, fileName), m_oldStatus(INVALID_STATUS) { basket()->addWatchedFile(fullPath()); loadFromFile(lazyLoad); } int AnimationContent::setWidthAndGetHeight(int /*width*/) { /*width -= 1*/; return m_movie.framePixmap().height() ; // TODO!!! } void AnimationContent::paint(TQPainter *painter, int width, int /*height*/, const TQColorGroup &/*colorGroup*/, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { /*width -= 1*/; // DEBUG_WIN << "AnimationContent::paint()"; const TQPixmap &frame = m_movie.framePixmap(); if (width >= frame.width()) // Full size painter->drawPixmap(0, 0, frame); else // Scalled down painter->drawPixmap(0, 0, frame); // TODO: Scall down } bool AnimationContent::loadFromFile(bool lazyLoad) { if (lazyLoad) return true; else return finishLazyLoad(); } bool AnimationContent::finishLazyLoad() { DEBUG_WIN << "Loading MovieContent From " + basket()->folderName() + fileName(); // return setMovie(TQMovie(fullPath())); bool success = false; TQByteArray content; if (basket()->loadFromFile(fullPath(), &content)) success = setMovie(TQMovie(content, content.size())); if (!success) setMovie(TQMovie()); return success; } bool AnimationContent::saveToFile() { // Impossible! return false; } TQString AnimationContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening animation..."); case OpenSeveral: return i18n("Opening animations..."); case OpenOneWith: return i18n("Opening animation with..."); case OpenSeveralWith: return i18n("Opening animations with..."); case OpenOneWithDialog: return i18n("Open animation with:"); case OpenSeveralWithDialog: return i18n("Open animations with:"); default: return ""; } } bool AnimationContent::setMovie(const TQMovie &movie) { if (!m_movie.isNull()) { // Disconnect? return false; } m_movie = movie; m_movie.connectUpdate( this, TQT_SLOT(movieUpdated(const TQRect&)) ); m_movie.connectResize( this, TQT_SLOT(movieResized(const TQSize&)) ); m_movie.connectStatus( this, TQT_SLOT(movieStatus(int)) ); contentChanged( m_movie.framePixmap().width() + 1 ); // TODO return true; } void AnimationContent::movieUpdated(const TQRect&) { note()->unbufferize(); note()->update(); } void AnimationContent::movieResized(const TQSize&) { note()->requestRetqlayout(); // ? } /** When a user drop a .gif file, for instance, we don't know if it is an image * or an animtion (gif file contain multiple images). * To determin that, we assume this is an animation and count the number of images. * TQMovie send, in this order: * - For a unique image: TQMovie::EndOfFrame, TQMovie::EndOfLoop, TQMovie::EndOfMovie. * - For animation: TQMovie::EndOfFrame... (for each image), TQMovie::EndOfLoop, * and it then restart that for each loop. */ void AnimationContent::movieStatus(int status) { DEBUG_WIN << "movieStatus()"; // At least two frames: it's an animation, everything is OK if (m_oldStatus == TQMovie::EndOfFrame && status == TQMovie::EndOfFrame) { movie().disconnectStatus(this); m_oldStatus = INVALID_STATUS; // if (note()->isFocused()) // When inserting a new note we ensure it visble // basket()->ensureNoteVisible(note()); // But after loading it has certainly grown and if it was } // Only one image: it's an image, change note's type else if (m_oldStatus == TQMovie::EndOfFrame && status == TQMovie::EndOfLoop) { movie().disconnectStatus(this); m_oldStatus = INVALID_STATUS; note()->setContent(new ImageContent(note(), fileName())); basket()->save(); //delete this; // CRASH, as always !!!!!!!!! //TQTimer::singleShot(0, this, TQT_SLOT(loadContent())); // Delayed to avoid crash! //TQTimer::singleShot(100, this, TQT_SLOT(saveProperties())); // We should save it's an image and not an animation // if (note()->isFocused()) // TQTimer::singleShot(25, note(), TQT_SLOT(delayedEnsureVisible())); } else m_oldStatus = status; } void AnimationContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) { exporter->stream << TQString("\"\"") .arg( exporter->dataFolderName + exporter->copyFile(fullPath(), /*createIt=*/true), TQString::number(movie().framePixmap().size().width()), TQString::number(movie().framePixmap().size().height()) ); } /** class FileContent: */ FileContent::FileContent(Note *parent, const TQString &fileName) : NoteContent(parent, fileName), m_previewJob(0) { basket()->addWatchedFile(fullPath()); setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods??? } int FileContent::setWidthAndGetHeight(int width) { m_linkDisplay.setWidth(width); return m_linkDisplay.height(); } void FileContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) { m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); } bool FileContent::loadFromFile(bool /*lazyLoad*/) { setFileName(fileName()); // File changed: get new file preview! return true; } void FileContent::toolTipInfos(TQStringList *keys, TQStringList *values) { // Get the size of the file: uint size = TQFileInfo(fullPath()).size(); TQString humanFileSize = KIO::convertSize((KIO::filesize_t)size); keys->append(i18n("Size")); values->append(humanFileSize); KMimeType::Ptr mime = KMimeType::findByURL(KURL(fullPath())); if (mime) { keys->append(i18n("Type")); values->append(mime->comment()); } KFileMetaInfo infos = KFileMetaInfo(KURL(fullPath())); if (infos.isValid() && !infos.isEmpty()) { TQStringList groups = infos.preferredKeys(); int i = 0; for (TQStringList::Iterator it = groups.begin(); i < 6 && it != groups.end(); ++it) { KFileMetaInfoItem metaInfoItem = infos.item(*it); if (!metaInfoItem.string().isEmpty()) { keys->append(metaInfoItem.translatedKey()); values->append(metaInfoItem.string()); ++i; } } } } int FileContent::zoneAt(const TQPoint &pos) { return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); } TQRect FileContent::zoneRect(int zone, const TQPoint &/*pos*/) { TQRect linkRect = m_linkDisplay.iconButtonRect(); if (zone == Note::Custom0) return TQRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() else if (zone == Note::Content) return linkRect; else return TQRect(); } TQString FileContent::zoneTip(int zone) { return (zone == Note::Custom0 ? i18n("Open this file") : TQString()); } void FileContent::setCursor(TQWidget *widget, int zone) { if (zone == Note::Custom0) widget->setCursor(TQt::PointingHandCursor); } int FileContent::xEditorIndent() { return m_linkDisplay.iconButtonRect().width() + 2; } TQString FileContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening file..."); case OpenSeveral: return i18n("Opening files..."); case OpenOneWith: return i18n("Opening file with..."); case OpenSeveralWith: return i18n("Opening files with..."); case OpenOneWithDialog: return i18n("Open file with:"); case OpenSeveralWithDialog: return i18n("Open files with:"); default: return ""; } } void FileContent::setFileName(const TQString &fileName) { NoteContent::setFileName(fileName); KURL url = KURL(fullPath()); if (linkLook()->previewEnabled()) m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), linkLook(), note()->font()); // FIXME: move iconForURL outside of NoteFactory !!!!! else m_linkDisplay.setLink(fileName, NoteFactory::iconForURL(url), TQPixmap(), linkLook(), note()->font()); startFetchingUrlPreview(); contentChanged(m_linkDisplay.minWidth()); } void FileContent::linkLookChanged() { fontChanged(); //setFileName(fileName()); //startFetchingUrlPreview(); } void FileContent::newPreview(const KFileItem*, const TQPixmap &preview) { LinkLook *linkLook = this->linkLook(); m_linkDisplay.setLink(fileName(), NoteFactory::iconForURL(KURL(fullPath())), (linkLook->previewEnabled() ? preview : TQPixmap()), linkLook, note()->font()); contentChanged(m_linkDisplay.minWidth()); } void FileContent::removePreview(const KFileItem*) { newPreview(0, TQPixmap()); } void FileContent::startFetchingUrlPreview() { KURL url(fullPath()); LinkLook *linkLook = this->linkLook(); // delete m_previewJob; if (!url.isEmpty() && linkLook->previewSize() > 0) { KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url); KURL::List urlList; urlList.append(filteredUrl); m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize()); connect( m_previewJob, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)), this, TQT_SLOT(newPreview(const KFileItem*, const TQPixmap&)) ); connect( m_previewJob, TQT_SIGNAL(failed(const KFileItem*)), this, TQT_SLOT(removePreview(const KFileItem*)) ); } } void FileContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString spaces; TQString fileName = exporter->copyFile(fullPath(), true); exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1)); } /** class SoundContent: */ SoundContent::SoundContent(Note *parent, const TQString &fileName) : FileContent(parent, fileName) { setFileName(fileName); // FIXME: TO THAT HERE BECAUSE NoteContent() constructor seems to don't be able to call virtual methods??? } TQString SoundContent::zoneTip(int zone) { return (zone == Note::Custom0 ? i18n("Open this sound") : TQString()); } void SoundContent::setHoveredZone(int oldZone, int newZone) { #ifdef WITHOUT_ARTS Q_UNUSED(oldZone); if (newZone == Note::Custom0 || newZone == Note::Content) std::cout << "Compiled without aRts: sound is not played." << std::endl; #else static KArtsDispatcher *s_dispatcher = new KArtsDispatcher(); // Needed for s_playObj (we don't use it directly) static KArtsServer *s_playServer = new KArtsServer(); static KDE::PlayObjectFactory *s_playFactory = new KDE::PlayObjectFactory(s_playServer); static KDE::PlayObject *s_playObj = 0; Q_UNUSED(s_dispatcher); // Avoid the compiler to tell us it is not used! if (newZone == Note::Custom0 || newZone == Note::Content) { // Start the sound preview: if (oldZone != Note::Custom0 && oldZone != Note::Content) { // Don't restart if it was already in one of those zones s_playObj = s_playFactory->createPlayObject(fullPath(), true); s_playObj->play(); } } else { // Stop the sound preview, if it was started: if (s_playObj) { s_playObj->halt(); delete s_playObj; s_playObj = 0; } } #endif } TQString SoundContent::messageWhenOpenning(OpenMessage where) { switch (where) { case OpenOne: return i18n("Opening sound..."); case OpenSeveral: return i18n("Opening sounds..."); case OpenOneWith: return i18n("Opening sound with..."); case OpenSeveralWith: return i18n("Opening sounds with..."); case OpenOneWithDialog: return i18n("Open sound with:"); case OpenSeveralWithDialog: return i18n("Open sounds with:"); default: return ""; } } /** class LinkContent: */ LinkContent::LinkContent(Note *parent, const KURL &url, const TQString &title, const TQString &icon, bool autoTitle, bool autoIcon) : NoteContent(parent), m_previewJob(0) { setLink(url, title, icon, autoTitle, autoIcon); } int LinkContent::setWidthAndGetHeight(int width) { m_linkDisplay.setWidth(width); return m_linkDisplay.height(); } void LinkContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) { m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); } void LinkContent::saveToNode(TQDomDocument &doc, TQDomElement &content) { content.setAttribute("title", title() ); content.setAttribute("icon", icon() ); content.setAttribute("autoTitle", (autoTitle() ? "true" : "false")); content.setAttribute("autoIcon", (autoIcon() ? "true" : "false")); TQDomText textNode = doc.createTextNode(url().prettyURL()); content.appendChild(textNode); } void LinkContent::toolTipInfos(TQStringList *keys, TQStringList *values) { keys->append(i18n("Target")); values->append(m_url.prettyURL()); } int LinkContent::zoneAt(const TQPoint &pos) { return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); } TQRect LinkContent::zoneRect(int zone, const TQPoint &/*pos*/) { TQRect linkRect = m_linkDisplay.iconButtonRect(); if (zone == Note::Custom0) return TQRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() else if (zone == Note::Content) return linkRect; else return TQRect(); } TQString LinkContent::zoneTip(int zone) { return (zone == Note::Custom0 ? i18n("Open this link") : TQString()); } void LinkContent::setCursor(TQWidget *widget, int zone) { if (zone == Note::Custom0) widget->setCursor(TQt::PointingHandCursor); } TQString LinkContent::statusBarMessage(int zone) { if (zone == Note::Custom0 || zone == Note::Content) return m_url.prettyURL(); else return ""; } KURL LinkContent::urlToOpen(bool /*with*/) { return NoteFactory::filteredURL(url());//KURIFilter::self()->filteredURI(url()); } TQString LinkContent::messageWhenOpenning(OpenMessage where) { if (url().isEmpty()) return i18n("Link have no URL to open."); switch (where) { case OpenOne: return i18n("Opening link target..."); case OpenSeveral: return i18n("Opening link targets..."); case OpenOneWith: return i18n("Opening link target with..."); case OpenSeveralWith: return i18n("Opening link targets with..."); case OpenOneWithDialog: return i18n("Open link target with:"); case OpenSeveralWithDialog: return i18n("Open link targets with:"); default: return ""; } } void LinkContent::setLink(const KURL &url, const TQString &title, const TQString &icon, bool autoTitle, bool autoIcon) { m_autoTitle = autoTitle; m_autoIcon = autoIcon; m_url = NoteFactory::filteredURL(KURL(url));//KURIFilter::self()->filteredURI(url); m_title = (autoTitle ? NoteFactory::titleForURL(m_url) : title); m_icon = (autoIcon ? NoteFactory::iconForURL(m_url) : icon); LinkLook *look = LinkLook::lookForURL(m_url); if (look->previewEnabled()) m_linkDisplay.setLink(m_title, m_icon, look, note()->font()); else m_linkDisplay.setLink(m_title, m_icon, TQPixmap(), look, note()->font()); startFetchingUrlPreview(); contentChanged(m_linkDisplay.minWidth()); } void LinkContent::linkLookChanged() { fontChanged(); } void LinkContent::newPreview(const KFileItem*, const TQPixmap &preview) { LinkLook *linkLook = LinkLook::lookForURL(url()); m_linkDisplay.setLink(title(), icon(), (linkLook->previewEnabled() ? preview : TQPixmap()), linkLook, note()->font()); contentChanged(m_linkDisplay.minWidth()); } void LinkContent::removePreview(const KFileItem*) { newPreview(0, TQPixmap()); } // Code dupicated from FileContent::startFetchingUrlPreview() void LinkContent::startFetchingUrlPreview() { KURL url = this->url(); LinkLook *linkLook = LinkLook::lookForURL(this->url()); // delete m_previewJob; if (!url.isEmpty() && linkLook->previewSize() > 0) { KURL filteredUrl = NoteFactory::filteredURL(url);//KURIFilter::self()->filteredURI(url); KURL::List urlList; urlList.append(filteredUrl); m_previewJob = KIO::filePreview(urlList, linkLook->previewSize(), linkLook->previewSize(), linkLook->iconSize()); connect( m_previewJob, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)), this, TQT_SLOT(newPreview(const KFileItem*, const TQPixmap&)) ); connect( m_previewJob, TQT_SIGNAL(failed(const KFileItem*)), this, TQT_SLOT(removePreview(const KFileItem*)) ); } } void LinkContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString linkTitle = title(); // TODO: // // Append address (useful for print version of the page/basket): // if (exportData.formatForImpression && (!autoTitle() && title() != NoteFactory::titleForURL(url().prettyURL()))) { // // The address is on a new line, unless title is empty (empty lines was replaced by  ): // if (linkTitle == " "/*" "*/) // linkTitle = url().prettyURL()/*""*/; // else // linkTitle = linkTitle + " <" + url().prettyURL() + ">"/*+ "
"*/; // //linkTitle += "" + url().prettyURL() + ""; // } KURL linkURL; /* TQFileInfo fInfo(url().path()); // DEBUG_WIN << url().path() // << "IsFile:" + TQString::number(fInfo.isFile()) // << "IsDir:" + TQString::number(fInfo.isDir()); if (exportData.embedLinkedFiles && fInfo.isFile()) { // DEBUG_WIN << "Embed file"; linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true); } else if (exportData.embedLinkedFolders && fInfo.isDir()) { // DEBUG_WIN << "Embed folder"; linkURL = exportData.dataFolderName + Basket::copyFile(url().path(), exportData.dataFolderPath, true); } else { // DEBUG_WIN << "Embed LINK"; */ linkURL = url(); /* } */ TQString spaces; exporter->stream << m_linkDisplay.toHtml(exporter, linkURL, linkTitle).replace("\n", "\n" + spaces.fill(' ', indent + 1)); } /** class LauncherContent: */ LauncherContent::LauncherContent(Note *parent, const TQString &fileName) : NoteContent(parent, fileName) { basket()->addWatchedFile(fullPath()); loadFromFile(/*lazyLoad=*/false); } int LauncherContent::setWidthAndGetHeight(int width) { m_linkDisplay.setWidth(width); return m_linkDisplay.height(); } void LauncherContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool isDefaultColor, bool isSelected, bool isHovered) { m_linkDisplay.paint(painter, 0, 0, width, height, colorGroup, isDefaultColor, isSelected, isHovered, isHovered && note()->hoveredZone() == Note::Custom0); } bool LauncherContent::loadFromFile(bool /*lazyLoad*/) // TODO: saveToFile() ?? Is it possible? { DEBUG_WIN << "Loading LauncherContent From " + basket()->folderName() + fileName(); KService service(fullPath()); setLauncher(service.name(), service.icon(), service.exec()); return true; } void LauncherContent::toolTipInfos(TQStringList *keys, TQStringList *values) { KService service(fullPath()); TQString exec = service.exec(); if (service.terminal()) exec = i18n("%1 (run in terminal)").arg(exec); if (!service.comment().isEmpty() && service.comment() != service.name()) { keys->append(i18n("Comment")); values->append(service.comment()); } keys->append(i18n("Command")); values->append(exec); } int LauncherContent::zoneAt(const TQPoint &pos) { return (m_linkDisplay.iconButtonAt(pos) ? 0 : Note::Custom0); } TQRect LauncherContent::zoneRect(int zone, const TQPoint &/*pos*/) { TQRect linkRect = m_linkDisplay.iconButtonRect(); if (zone == Note::Custom0) return TQRect(linkRect.width(), 0, note()->width(), note()->height()); // Too wide and height, but it will be clipped by Note::zoneRect() else if (zone == Note::Content) return linkRect; else return TQRect(); } TQString LauncherContent::zoneTip(int zone) { return (zone == Note::Custom0 ? i18n("Launch this application") : TQString()); } void LauncherContent::setCursor(TQWidget *widget, int zone) { if (zone == Note::Custom0) widget->setCursor(TQt::PointingHandCursor); } KURL LauncherContent::urlToOpen(bool with) { if (KService(fullPath()).exec().isEmpty()) return KURL(); return (with ? KURL() : KURL(fullPath())); // Can open the appliation, but not with another application :-) } TQString LauncherContent::messageWhenOpenning(OpenMessage where) { if (KService(fullPath()).exec().isEmpty()) return i18n("The launcher have no command to run."); switch (where) { case OpenOne: return i18n("Launching application..."); case OpenSeveral: return i18n("Launching applications..."); case OpenOneWith: case OpenSeveralWith: case OpenOneWithDialog: case OpenSeveralWithDialog: // TODO: "Open this application with this file as parameter"? default: return ""; } } void LauncherContent::setLauncher(const TQString &name, const TQString &icon, const TQString &exec) { m_name = name; m_icon = icon; m_exec = exec; m_linkDisplay.setLink(name, icon, LinkLook::launcherLook, note()->font()); contentChanged(m_linkDisplay.minWidth()); } void LauncherContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString spaces; TQString fileName = exporter->copyFile(fullPath(), /*createIt=*/true); exporter->stream << m_linkDisplay.toHtml(exporter, KURL(exporter->dataFolderName + fileName), "").replace("\n", "\n" + spaces.fill(' ', indent + 1)); } /** class ColorContent: */ const int ColorContent::RECT_MARGIN = 2; ColorContent::ColorContent(Note *parent, const TQColor &color) : NoteContent(parent) { setColor(color); } int ColorContent::setWidthAndGetHeight(int /*width*/) // We do not need width because we can't word-break, and width is always >= minWidth() { // FIXME: Duplicate from setColor(): TQRect textRect = TQFontMetrics(note()->font()).boundingRect(color().name()); int rectHeight = (textRect.height() + 2)*3/2; return rectHeight; } void ColorContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { // FIXME: Duplicate from setColor(): TQRect textRect = TQFontMetrics(note()->font()).boundingRect(color().name()); int rectHeight = (textRect.height() + 2)*3/2; int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. // FIXME: Duplicate from CommonColorSelector::drawColorRect: // Fill: painter->fillRect(1, 1, rectWidth - 2, rectHeight - 2, color()); // Stroke: TQColor stroke = color().dark(125); painter->setPen(stroke); painter->drawLine(1, 0, rectWidth - 2, 0); painter->drawLine(0, 1, 0, rectHeight - 2); painter->drawLine(1, rectHeight - 1, rectWidth - 2, rectHeight - 1); painter->drawLine(rectWidth - 1, 1, rectWidth - 1, rectHeight - 2); // Round corners: painter->setPen(Tools::mixColor(color(), stroke)); painter->drawPoint(1, 1); painter->drawPoint(1, rectHeight - 2); painter->drawPoint(rectWidth - 2, rectHeight - 2); painter->drawPoint(rectWidth - 2, 1); // Draw the text: painter->setFont(note()->font()); painter->setPen(colorGroup.text()); painter->drawText(rectWidth + RECT_MARGIN, 0, width - rectWidth - RECT_MARGIN, height, TQt::AlignAuto | TQt::AlignVCenter, color().name()); } void ColorContent::saveToNode(TQDomDocument &doc, TQDomElement &content) { TQDomText textNode = doc.createTextNode(color().name()); content.appendChild(textNode); } void ColorContent::toolTipInfos(TQStringList *keys, TQStringList *values) { int hue, saturation, value; m_color.getHsv(&hue, &saturation, &value); keys->append(i18n("RGB Colorspace: Red/Green/Blue", "RGB")); values->append(i18n("Red: %1, Green: %2, Blue: %3,").arg(TQString::number(m_color.red()), TQString::number(m_color.green()), TQString::number(m_color.blue()))); keys->append(i18n("HSV Colorspace: Hue/Saturation/Value", "HSV")); values->append(i18n("Hue: %1, Saturation: %2, Value: %3,").arg(TQString::number(hue), TQString::number(saturation), TQString::number(value))); static TQString cssColors[] = { "aqua", "00ffff", "black", "000000", "blue", "0000ff", "fuchsia", "ff00ff", "gray", "808080", "green", "008000", "lime", "00ff00", "maroon", "800000", "navy", "000080", "olive", "808000", "purple", "800080", "red", "ff0000", "silver", "c0c0c0", "teal", "008080", "white", "ffffff", "yellow", "ffff00" }; static TQString cssExtendedColors[] = { "aliceblue", "f0f8ff", "antiquewhite", "faebd7", "aquamarine", "7fffd4", "azure", "f0ffff", "beige", "f5f5dc", "bisque", "ffe4c4", "blanchedalmond", "ffebcd", "blueviolet", "8a2be2", "brown", "a52a2a", "burlywood", "deb887", "cadetblue", "5f9ea0", "chartreuse", "7fff00", "chocolate", "d2691e", "coral", "ff7f50", "cornflowerblue", "6495ed", "cornsilk", "fff8dc", "crimson", "dc1436", "cyan", "00ffff", "darkblue", "00008b", "darkcyan", "008b8b", "darkgoldenrod", "b8860b", "darkgray", "a9a9a9", "darkgreen", "006400", "darkkhaki", "bdb76b", "darkmagenta", "8b008b", "darkolivegreen", "556b2f", "darkorange", "ff8c00", "darkorchid", "9932cc", "darkred", "8b0000", "darksalmon", "e9967a", "darkseagreen", "8fbc8f", "darkslateblue", "483d8b", "darkslategray", "2f4f4f", "darkturquoise", "00ced1", "darkviolet", "9400d3", "deeppink", "ff1493", "deepskyblue", "00bfff", "dimgray", "696969", "dodgerblue", "1e90ff", "firebrick", "b22222", "floralwhite", "fffaf0", "forestgreen", "228b22", "gainsboro", "dcdcdc", "ghostwhite", "f8f8ff", "gold", "ffd700", "goldenrod", "daa520", "greenyellow", "adff2f", "honeydew", "f0fff0", "hotpink", "ff69b4", "indianred", "cd5c5c", "indigo", "4b0082", "ivory", "fffff0", "khaki", "f0e68c", "lavender", "e6e6fa", "lavenderblush", "fff0f5", "lawngreen", "7cfc00", "lemonchiffon", "fffacd", "lightblue", "add8e6", "lightcoral", "f08080", "lightcyan", "e0ffff", "lightgoldenrodyellow", "fafad2", "lightgreen", "90ee90", "lightgrey", "d3d3d3", "lightpink", "ffb6c1", "lightsalmon", "ffa07a", "lightseagreen", "20b2aa", "lightskyblue", "87cefa", "lightslategray", "778899", "lightsteelblue", "b0c4de", "lightyellow", "ffffe0", "limegreen", "32cd32", "linen", "faf0e6", "magenta", "ff00ff", "mediumaquamarine", "66cdaa", "mediumblue", "0000cd", "mediumorchid", "ba55d3", "mediumpurple", "9370db", "mediumseagreen", "3cb371", "mediumslateblue", "7b68ee", "mediumspringgreen", "00fa9a", "mediumturquoise", "48d1cc", "mediumvioletred", "c71585", "midnightblue", "191970", "mintcream", "f5fffa", "mistyrose", "ffe4e1", "tqmoccasin", "ffe4b5", "navajowhite", "ffdead", "oldlace", "fdf5e6", "olivedrab", "6b8e23", "orange", "ffa500", "orangered", "ff4500", "orchid", "da70d6", "palegoldenrod", "eee8aa", "palegreen", "98fb98", "paleturquoise", "afeeee", "palevioletred", "db7093", "papayawhip", "ffefd5", "peachpuff", "ffdab9", "peru", "cd853f", "pink", "ffc0cb", "plum", "dda0dd", "powderblue", "b0e0e6", "rosybrown", "bc8f8f", "royalblue", "4169e1", "saddlebrown", "8b4513", "salmon", "fa8072", "sandybrown", "f4a460", "seagreen", "2e8b57", "seashell", "fff5ee", "sienna", "a0522d", "skyblue", "87ceeb", "slateblue", "6a5acd", "slategray", "708090", "snow", "fffafa", "springgreen", "00ff7f", "steelblue", "4682b4", "tan", "d2b48c", "thistle", "d8bfd8", "tomato", "ff6347", "turquoise", "40e0d0", "violet", "ee82ee", "wheat", "f5deb3", "whitesmoke", "f5f5f5", "yellowgreen", "9acd32" }; TQString colorHex = color().name().mid(1); // Take the hexadecimal name of the color, without the '#'. bool cssColorFound = false; for (int i = 0; i < 2*16; i += 2) { if (colorHex == cssColors[i+1]) { keys->append(i18n("CSS Color Name")); values->append(cssColors[i]); cssColorFound = true; break; } } if (!cssColorFound) for (int i = 0; i < 2*124; i += 2) { if (colorHex == cssExtendedColors[i+1]) { keys->append(i18n("CSS Extended Color Name")); values->append(cssExtendedColors[i]); break; } } keys->append(i18n("Is Web Color")); values->append(Tools::isWebColor(color()) ? i18n("Yes") : i18n("No")); } void ColorContent::setColor(const TQColor &color) { m_color = color; TQRect textRect = TQFontMetrics(note()->font()).boundingRect(color.name()); int rectHeight = (textRect.height() + 2)*3/2; int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. 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. } void ColorContent::addAlternateDragObjects(KMultipleDrag *dragObject) { dragObject->addDragObject( new TQColorDrag(color()) ); // addDragObject(new KColorDrag( note->color(), 0 )); // addDragObject(new TQTextDrag( note->color().name(), 0 )); /* // Creata and add the TQDragObject: storedDrag = new TQStoredDrag("application/x-color"); storedDrag->setEncodedData(*array); dragObject->addDragObject(storedDrag); delete array;*/ } void ColorContent::exportToHTML(HTMLExporter *exporter, int /*indent*/) { // FIXME: Duplicate from setColor(): TODO: rectSize() TQRect textRect = TQFontMetrics(note()->font()).boundingRect(color().name()); int rectHeight = (textRect.height() + 2)*3/2; int rectWidth = rectHeight * 14 / 10; // 1.4 times the height, like A4 papers. TQString fileName = /*Tools::fileNameForNewFile(*/TQString(TQString("color_%1.png").arg(color().name()).lower().mid(1))/*, exportData.iconsFolderPath)*/; TQString fullPath = exporter->iconsFolderPath + fileName; TQPixmap colorIcon = KColorCombo2::colorRectPixmap(color(), /*isDefault=*/false, rectWidth, rectHeight); colorIcon.save(fullPath, "PNG"); TQString iconHtml = TQString("\"\"") .arg(exporter->iconsFolderName + fileName, TQString::number(colorIcon.width()), TQString::number(colorIcon.height())); exporter->stream << iconHtml + " " + color().name(); } /** class UnknownContent: */ const int UnknownContent::DECORATION_MARGIN = 2; UnknownContent::UnknownContent(Note *parent, const TQString &fileName) : NoteContent(parent, fileName) { basket()->addWatchedFile(fullPath()); loadFromFile(/*lazyLoad=*/false); } int UnknownContent::setWidthAndGetHeight(int width) { width -= 1; TQRect textRect = TQFontMetrics(note()->font()).boundingRect(0, 0, width, 500000, TQt::AlignAuto | TQt::AlignTop | TQt::WordBreak, m_mimeTypes); return DECORATION_MARGIN + textRect.height() + DECORATION_MARGIN; } // TODO: Move this function from note.cpp to class Tools: extern void drawGradient( TQPainter *p, const TQColor &colorTop, const TQColor & colorBottom, int x, int y, int w, int h, bool sunken, bool horz, bool flat ); /*const*/ void UnknownContent::paint(TQPainter *painter, int width, int height, const TQColorGroup &colorGroup, bool /*isDefaultColor*/, bool /*isSelected*/, bool /*isHovered*/) { width -= 1; painter->setPen(colorGroup.text()); // FIXME: Duplicate from ColorContent::paint() and CommonColorSelector::drawColorRect: // Fill with gradient: drawGradient(painter, colorGroup.background(), colorGroup.background().dark(110), 1, 1, width - 2, height - 2, /*sunken=*/false, /*horz=*/true, /*flat=*/false); // Stroke: TQColor stroke = Tools::mixColor(colorGroup.background(), colorGroup.text()); painter->setPen(stroke); painter->drawLine(1, 0, width - 2, 0); painter->drawLine(0, 1, 0, height - 2); painter->drawLine(1, height - 1, width - 2, height - 1); painter->drawLine(width - 1, 1, width - 1, height - 2); // Round corners: painter->setPen(Tools::mixColor(colorGroup.background(), stroke)); painter->drawPoint(1, 1); painter->drawPoint(1, height - 2); painter->drawPoint(width - 2, height - 2); painter->drawPoint(width - 2, 1); painter->setPen(colorGroup.text()); painter->drawText(DECORATION_MARGIN, DECORATION_MARGIN, width - 2*DECORATION_MARGIN, height - 2*DECORATION_MARGIN, TQt::AlignAuto | TQt::AlignVCenter | TQt::WordBreak, m_mimeTypes); } bool UnknownContent::loadFromFile(bool /*lazyLoad*/) { DEBUG_WIN << "Loading UnknownContent From " + basket()->folderName() + fileName(); TQFile file(fullPath()); if (file.open(IO_ReadOnly)) { TQDataStream stream(&file); TQString line; m_mimeTypes = ""; // Get the MIME-types names: do { if (!stream.atEnd()) { stream >> line; if (!line.isEmpty()) { if (m_mimeTypes.isEmpty()) m_mimeTypes += line; else m_mimeTypes += TQString("\n") + line; } } } while (!line.isEmpty() && !stream.atEnd()); file.close(); } TQRect textRect = TQFontMetrics(note()->font()).boundingRect(0, 0, /*width=*/1, 500000, TQt::AlignAuto | TQt::AlignTop | TQt::WordBreak, m_mimeTypes); contentChanged(DECORATION_MARGIN + textRect.width() + DECORATION_MARGIN + 1); return true; } void UnknownContent::addAlternateDragObjects(KMultipleDrag *dragObject) { TQFile file(fullPath()); if (file.open(IO_ReadOnly)) { TQDataStream stream(&file); // Get the MIME types names: TQValueList mimes; TQString line; do { if (!stream.atEnd()) { stream >> line; if (!line.isEmpty()) mimes.append(line); } } while (!line.isEmpty() && !stream.atEnd()); // Add the streams: TQ_UINT64 size; // TODO: It was TQ_UINT32 in version 0.5.0 ! TQByteArray *array; TQStoredDrag *storedDrag; for (uint i = 0; i < mimes.count(); ++i) { // Get the size: stream >> size; // Allocate memory to retreive size bytes and store them: array = new TQByteArray(size); stream.readRawBytes(array->data(), size); // Creata and add the TQDragObject: storedDrag = new TQStoredDrag(*(mimes.at(i))); storedDrag->setEncodedData(*array); dragObject->addDragObject(storedDrag); delete array; // FIXME: Should we? } file.close(); } } void UnknownContent::exportToHTML(HTMLExporter *exporter, int indent) { TQString spaces; exporter->stream << "
" << mimeTypes().replace("\n", "\n" + spaces.fill(' ', indent + 1 + 1)) << "
"; } void NoteFactory__loadNode(const TQDomElement &content, const TQString &lowerTypeName, Note *parent, bool lazyLoad) { if (lowerTypeName == "text") new TextContent( parent, content.text(), lazyLoad ); else if (lowerTypeName == "html") new HtmlContent( parent, content.text(), lazyLoad ); else if (lowerTypeName == "image") new ImageContent( parent, content.text(), lazyLoad ); else if (lowerTypeName == "animation") new AnimationContent( parent, content.text(), lazyLoad ); else if (lowerTypeName == "sound") new SoundContent( parent, content.text() ); else if (lowerTypeName == "file") new FileContent( parent, content.text() ); else if (lowerTypeName == "link") { bool autoTitle = content.attribute("title") == content.text(); bool autoIcon = content.attribute("icon") == NoteFactory::iconForURL(KURL(content.text())); autoTitle = XMLWork::trueOrFalse( content.attribute("autoTitle"), autoTitle); autoIcon = XMLWork::trueOrFalse( content.attribute("autoIcon"), autoIcon ); new LinkContent( parent, KURL(content.text()), content.attribute("title"), content.attribute("icon"), autoTitle, autoIcon ); } else if (lowerTypeName == "launcher") new LauncherContent( parent, content.text() ); else if (lowerTypeName == "color") new ColorContent( parent, TQColor(content.text()) ); else if (lowerTypeName == "unknown") new UnknownContent( parent, content.text() ); } #include "notecontent.moc"