/*************************************************************************** * 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. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "formatimporter.h" #include "notecontent.h" #include "notefactory.h" #include "bnpview.h" #include "basket.h" #include "global.h" #include "xmlwork.h" #include "tools.h" bool FormatImporter::shouldImportBaskets() { // We should import if the application have not successfully loaded any basket... if (Global::bnpView->firstListViewItem()) return false; // ... And there is at least one folder in the save folder, with a ".basket" file inside that folder. TQDir dir(Global::savesFolder(), TQString(), TQDir::Name | TQDir::IgnoreCase, TQDir::Dirs | TQDir::NoSymLinks); TQStringList list = dir.entryList(); for (TQStringList::Iterator it = list.begin(); it != list.end(); ++it) if (*it != "." && *it != ".." && dir.exists(Global::savesFolder() + *it + "/.basket")) return true; return false; } void FormatImporter::copyFolder(const TQString &folder, const TQString &newFolder) { copyFinished = false; TDEIO::CopyJob *copyJob = TDEIO::copyAs(KURL(folder), KURL(newFolder), /*showProgressInfo=*/false); connect( copyJob, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotCopyingDone(TDEIO::Job*)) ); while (!copyFinished) kapp->processEvents(); } void FormatImporter::moveFolder(const TQString &folder, const TQString &newFolder) { copyFinished = false; TDEIO::CopyJob *copyJob = TDEIO::moveAs(KURL(folder), KURL(newFolder), /*showProgressInfo=*/false); connect( copyJob, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(slotCopyingDone(TDEIO::Job*)) ); while (!copyFinished) kapp->processEvents(); } void FormatImporter::slotCopyingDone(TDEIO::Job *) { // std::cout << "Copy finished of " + from.path() + " to " + to.path() << std::endl; copyFinished = true; } void FormatImporter::importBaskets() { std::cout << "Import Baskets: Preparing..." << std::endl; // Some preliminary preparations (create the destination folders and the basket tree file): TQDir dirPrep; dirPrep.mkdir(Global::savesFolder()); dirPrep.mkdir(Global::basketsFolder()); TQDomDocument document("basketTree"); TQDomElement root = document.createElement("basketTree"); document.appendChild(root); // First up, establish a list of every baskets, ensure the old order (if any), and count them. TQStringList baskets; // Read the 0.5.0 baskets order: TQDomDocument *doc = XMLWork::openFile("container", Global::savesFolder() + "container.baskets"); if (doc != 0) { TQDomElement docElem = doc->documentElement(); TQDomElement basketsElem = XMLWork::getElement(docElem, "baskets"); TQDomNode n = basketsElem.firstChild(); while (!n.isNull()) { TQDomElement e = n.toElement(); if ((!e.isNull()) && e.tagName() == "basket") baskets.append(e.text()); n = n.nextSibling(); } } // Then load the baskets that weren't loaded (import < 0.5.0 ones): TQDir dir(Global::savesFolder(), TQString(), TQDir::Name | TQDir::IgnoreCase, TQDir::Dirs | TQDir::NoSymLinks); TQStringList list = dir.entryList(); if (list.count() > 2) // Pass "." and ".." for (TQStringList::Iterator it = list.begin(); it != list.end(); ++it) // For each folder if (*it != "." && *it != ".." && dir.exists(Global::savesFolder() + *it + "/.basket")) // If it can be a basket folder if ( baskets.find((*it) + "/") == baskets.end() && baskets.find(*it) == baskets.end() ) // And if it is not already in the imported baskets list baskets.append(*it); std::cout << "Import Baskets: Found " << baskets.count() << " baskets to import." << std::endl; // Import every baskets: int i = 0; for (TQStringList::iterator it = baskets.begin(); it != baskets.end(); ++it) { ++i; std::cout << "Import Baskets: Importing basket " << i << " of " << baskets.count() << "..." << std::endl; // Move the folder to the new repository (normal basket) or copy the folder (mirorred folder): TQString folderName = *it; if (folderName.startsWith("/")) { // It was a folder mirror: KMessageBox::information(0, i18n("

Folder mirroring is not possible anymore.

" "

The folder %1 has been copied for the basket needs. You can either delete this folder or delete the basket, or use both. But remember that " "modifying one will not modify the other anymore as they are now separate entities.

").arg(folderName), i18n("Folder Mirror Import"), "", KMessageBox::AllowLink); // Also modify folderName to be only the folder name and not the full path anymore: TQString newFolderName = folderName; if (newFolderName.endsWith("/")) newFolderName = newFolderName.left(newFolderName.length() - 1); newFolderName = newFolderName.mid(newFolderName.findRev('/') + 1); newFolderName = Tools::fileNameForNewFile(newFolderName, Global::basketsFolder()); FormatImporter f; f.copyFolder(folderName, Global::basketsFolder() + newFolderName); folderName = newFolderName; } else dir.rename(Global::savesFolder() + folderName, Global::basketsFolder() + folderName); // Move the folder // Import the basket structure file and get the properties (to add them in the tree basket-properties cache): TQDomElement properties = importBasket(folderName); // Add it to the XML document: TQDomElement basketElement = document.createElement("basket"); root.appendChild(basketElement); basketElement.setAttribute("folderName", folderName); basketElement.appendChild(properties); } // Finalize (write to disk and delete now useless files): std::cout << "Import Baskets: Finalizing..." << std::endl; TQFile file(Global::basketsFolder() + "baskets.xml"); if (file.open(IO_WriteOnly)) { TQTextStream stream(&file); stream.setEncoding(TQTextStream::UnicodeUTF8); TQString xml = document.toString(); stream << "\n"; stream << xml; file.close(); } Tools::deleteRecursively(Global::savesFolder() + ".tmp"); dir.remove(Global::savesFolder() + "container.baskets"); std::cout << "Import Baskets: Finished." << std::endl; } TQDomElement FormatImporter::importBasket(const TQString &folderName) { // Load the XML file: TQDomDocument *document = XMLWork::openFile("basket", Global::basketsFolder() + folderName + "/.basket"); if (!document) { std::cout << "Import Baskets: Failed to read the basket file!" << std::endl; return TQDomElement(); } TQDomElement docElem = document->documentElement(); // Import properties (change to , and figure out if is a checklist or not): TQDomElement properties = XMLWork::getElement(docElem, "properties"); TQDomElement background = XMLWork::getElement(properties, "background"); TQColor backgroundColor = TQColor(background.attribute("color")); if (backgroundColor.isValid() && (backgroundColor != TDEGlobalSettings::baseColor())) { // Use the default color if it was already that color: TQDomElement appearance = document->createElement("appearance"); appearance.setAttribute("backgroundColor", backgroundColor.name()); properties.appendChild(appearance); } TQDomElement disposition = document->createElement("disposition"); disposition.setAttribute("mindMap", "false"); disposition.setAttribute("columnCount", "1"); disposition.setAttribute("free", "false"); bool isCheckList = XMLWork::trueOrFalse( XMLWork::getElementText(properties, "showCheckBoxes", "") ); // Insert all notes in a group (column): 1/ rename "items" to "group", 2/ add "notes" to root, 3/ move "group" into "notes" TQDomElement column = XMLWork::getElement(docElem, "items"); column.setTagName("group"); TQDomElement notes = document->createElement("notes"); notes.appendChild(column); docElem.appendChild(notes); // Import notes from older representations: TQDomNode n = column.firstChild(); while ( ! n.isNull() ) { TQDomElement e = n.toElement(); if (!e.isNull()) { e.setTagName("note"); TQDomElement content = XMLWork::getElement(e, "content"); // Add Check tag: if (isCheckList) { bool isChecked = XMLWork::trueOrFalse(e.attribute("checked", "false")); XMLWork::addElement(*document, e, "tags", (isChecked ? "todo_done" : "todo_unchecked")); } // Import annotations as folded groups: TQDomElement parentE = column; TQString annotations = XMLWork::getElementText(e, "annotations", ""); if (!annotations.isEmpty()) { TQDomElement annotGroup = document->createElement("group"); column.insertBefore(annotGroup, e); annotGroup.setAttribute("folded", "true"); annotGroup.appendChild(e); parentE = annotGroup; // Create the text note and add it to the DOM tree: TQDomElement annotNote = document->createElement("note"); annotNote.setAttribute("type", "text"); annotGroup.appendChild(annotNote); TQString annotFileName = Tools::fileNameForNewFile("annotations1.txt", Basket::fullPathForFolderName(folderName)); TQString annotFullPath = Basket::fullPathForFolderName(folderName) + "/" + annotFileName; TQFile file(annotFullPath); if (file.open(IO_WriteOnly)) { TQTextStream stream(&file); stream << annotations; file.close(); } XMLWork::addElement(*document, annotNote, "content", annotFileName); n = annotGroup; } // Import Launchers from 0.3.x, 0.4.0 and 0.5.0-alphas: TQString runCommand = e.attribute("runcommand"); // Keep compatibility with 0.4.0 and 0.5.0-alphas versions runCommand = XMLWork::getElementText(e, "action", runCommand); // Keep compatibility with 0.3.x versions if ( ! runCommand.isEmpty() ) { // An import should be done // Prepare the launcher note: TQString title = content.attribute("title", ""); TQString icon = content.attribute("icon", ""); if (title.isEmpty()) title = runCommand; if (icon.isEmpty()) icon = NoteFactory::iconForCommand(runCommand); // Import the launcher note: // Adapted version of "TQString launcherName = NoteFactory::createNoteLauncherFile(runCommand, title, icon, this)": TQString launcherContent = TQString( "[Desktop Entry]\n" "Exec=%1\n" "Name=%2\n" "Icon=%3\n" "Encoding=UTF-8\n" "Type=Application\n").arg(runCommand, title, icon.isEmpty() ? TQString("application-x-executable") : icon); TQString launcherFileName = Tools::fileNameForNewFile("launcher.desktop", Global::basketsFolder() + folderName /*+ "/"*/); TQString launcherFullPath = Global::basketsFolder() + folderName /*+ "/"*/ + launcherFileName; TQFile file(launcherFullPath); if (file.open(IO_WriteOnly)) { TQTextStream stream(&file); stream.setEncoding(TQTextStream::UnicodeUTF8); stream << launcherContent; file.close(); } // Add the element to the DOM: TQDomElement launcherElem = document->createElement("note"); parentE.insertBefore(launcherElem, e); launcherElem.setAttribute("type", "launcher"); XMLWork::addElement(*document, launcherElem, "content", launcherFileName); } // Import unknown ns to 0.6.0: if (e.attribute("type") == "unknow") e.setAttribute("type", "unknown"); // Import links from version < 0.5.0: if (!content.attribute("autotitle").isEmpty() && content.attribute("autoTitle").isEmpty()) content.setAttribute("autoTitle", content.attribute("autotitle")); if (!content.attribute("autoicon").isEmpty() && content.attribute("autoIcon").isEmpty()) content.setAttribute("autoIcon", content.attribute("autoicon")); } n = n.nextSibling(); } // Save the resulting XML file: TQFile file(Global::basketsFolder() + folderName + "/.basket"); if (file.open(IO_WriteOnly)) { TQTextStream stream(&file); stream.setEncoding(TQTextStream::UnicodeUTF8); // TQString xml = document->toString(); // stream << "\n"; // stream << xml; stream << document->toString(); // Document is ALREADY using UTF-8 file.close(); } else std::cout << "Import Baskets: Failed to save the basket file!" << std::endl; // Return the newly created properties (to put in the basket tree): return properties; } #include "formatimporter.moc"