File indexing completed on 2024-04-21 09:41:20
0001 // -*- indent-tabs-mode:nil -*- 0002 // vim: set ts=4 sts=4 sw=4 et: 0003 /* This file is part of the KDE project 0004 Copyright (C) 2000 David Faure <faure@kde.org> 0005 Copyright (C) 2002-2003 Alexander Kellett <lypanov@kde.org> 0006 0007 This program is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU General Public 0009 License version 2 or at your option version 3 as published by 0010 the Free Software Foundation. 0011 0012 This program is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 General Public License for more details. 0016 0017 You should have received a copy of the GNU General Public License 0018 along with this program; see the file COPYING. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "importers.h" 0024 #include "globalbookmarkmanager.h" 0025 0026 #include "kbookmarkmodel/model.h" 0027 #include "toplevel.h" // for KEBApp 0028 0029 #include "keditbookmarks_debug.h" 0030 0031 #include <QFileDialog> 0032 #include <QStandardPaths> 0033 0034 #include <KBookmark> 0035 #include <KBookmarkManager> 0036 #include <KMessageBox> 0037 0038 #include <kbookmarkdombuilder.h> 0039 #include <kbookmarkimporter.h> 0040 #include <kbookmarkimporter_ie.h> 0041 #include <kbookmarkimporter_ns.h> 0042 #include <kbookmarkimporter_opera.h> 0043 #include <kwidgetsaddons_version.h> 0044 0045 ImportCommand::ImportCommand(KBookmarkModel *model) 0046 : QUndoCommand() 0047 , m_model(model) 0048 , m_utf8(false) 0049 , m_folder(false) 0050 , m_cleanUpCmd(nullptr) 0051 { 0052 } 0053 0054 void ImportCommand::setVisibleName(const QString &visibleName) 0055 { 0056 m_visibleName = visibleName; 0057 setText(i18nc("(qtundo-format)", "Import %1 Bookmarks", visibleName)); 0058 } 0059 0060 QString ImportCommand::folder() const 0061 { 0062 return m_folder ? i18n("%1 Bookmarks", visibleName()) : QString(); 0063 } 0064 0065 ImportCommand *ImportCommand::importerFactory(KBookmarkModel *model, const QString &type) 0066 { 0067 if (type == QLatin1String("Galeon")) 0068 return new GaleonImportCommand(model); 0069 else if (type == QLatin1String("IE")) 0070 return new IEImportCommand(model); 0071 else if (type == QLatin1String("KDE2")) 0072 return new KDE2ImportCommand(model); 0073 else if (type == QLatin1String("Opera")) 0074 return new OperaImportCommand(model); 0075 // else if (type == "Crashes") return new CrashesImportCommand(); 0076 else if (type == QLatin1String("Moz")) 0077 return new MozImportCommand(model); 0078 else if (type == QLatin1String("NS")) 0079 return new NSImportCommand(model); 0080 else { 0081 qCCritical(KEDITBOOKMARKS_LOG) << "ImportCommand::importerFactory() - invalid type (" << type << ")!"; 0082 return nullptr; 0083 } 0084 } 0085 0086 ImportCommand *ImportCommand::performImport(KBookmarkModel *model, const QString &type, QWidget *top) 0087 { 0088 ImportCommand *importer = ImportCommand::importerFactory(model, type); 0089 0090 Q_ASSERT(importer); 0091 0092 QString mydirname = importer->requestFilename(); 0093 if (mydirname.isEmpty()) { 0094 delete importer; 0095 return nullptr; 0096 } 0097 0098 int answer = KMessageBox::questionTwoActionsCancel(top, 0099 i18n("Import as a new subfolder or replace all the current bookmarks?"), 0100 i18nc("@title:window", "%1 Import", importer->visibleName()), 0101 KGuiItem(i18n("As New Folder")), 0102 KGuiItem(i18n("Replace"))); 0103 0104 if (answer == KMessageBox::Cancel) { 0105 delete importer; 0106 return nullptr; 0107 } 0108 0109 importer->import(mydirname, answer == KMessageBox::ButtonCode::PrimaryAction); 0110 return importer; 0111 } 0112 0113 void ImportCommand::doCreateHoldingFolder(KBookmarkGroup &bkGroup) 0114 { 0115 bkGroup = GlobalBookmarkManager::self()->mgr()->root().createNewFolder(folder()); 0116 bkGroup.setIcon(m_icon); 0117 m_group = bkGroup.address(); 0118 } 0119 0120 void ImportCommand::redo() 0121 { 0122 KBookmarkGroup bkGroup; 0123 0124 if (!folder().isNull()) { 0125 doCreateHoldingFolder(bkGroup); 0126 0127 } else { 0128 // import into the root, after cleaning it up 0129 bkGroup = GlobalBookmarkManager::self()->root(); 0130 delete m_cleanUpCmd; 0131 m_cleanUpCmd = DeleteCommand::deleteAll(m_model, bkGroup); 0132 0133 new DeleteCommand(m_model, bkGroup.address(), true /* contentOnly */, m_cleanUpCmd); 0134 m_cleanUpCmd->redo(); 0135 0136 // import at the root 0137 m_group = QLatin1String(""); 0138 } 0139 0140 doExecute(bkGroup); 0141 0142 // notify the model that the data has changed 0143 // 0144 // FIXME Resetting the model completely has the unwanted 0145 // side-effect of collapsing all items in tree views 0146 // (and possibly other side effects) 0147 m_model->resetModel(); 0148 } 0149 0150 void ImportCommand::undo() 0151 { 0152 if (!folder().isEmpty()) { 0153 // we created a group -> just delete it 0154 DeleteCommand cmd(m_model, m_group); 0155 cmd.redo(); 0156 0157 } else { 0158 // we imported at the root -> delete everything 0159 KBookmarkGroup root = GlobalBookmarkManager::self()->root(); 0160 QUndoCommand *cmd = DeleteCommand::deleteAll(m_model, root); 0161 0162 cmd->redo(); 0163 delete cmd; 0164 0165 // and recreate what was there before 0166 m_cleanUpCmd->undo(); 0167 } 0168 } 0169 0170 QString ImportCommand::affectedBookmarks() const 0171 { 0172 QString rootAdr = GlobalBookmarkManager::self()->root().address(); 0173 if (m_group == rootAdr) 0174 return m_group; 0175 else 0176 return KBookmark::parentAddress(m_group); 0177 } 0178 0179 /* -------------------------------------- */ 0180 0181 QString MozImportCommand::requestFilename() const 0182 { 0183 static KMozillaBookmarkImporterImpl importer; 0184 return importer.findDefaultLocation(); 0185 } 0186 0187 QString NSImportCommand::requestFilename() const 0188 { 0189 static NSBookmarkImporterImpl importer; 0190 return importer.findDefaultLocation(); 0191 } 0192 0193 QString OperaImportCommand::requestFilename() const 0194 { 0195 static OperaBookmarkImporterImpl importer; 0196 return importer.findDefaultLocation(); 0197 } 0198 0199 QString IEImportCommand::requestFilename() const 0200 { 0201 static IEBookmarkImporterImpl importer; 0202 return importer.findDefaultLocation(); 0203 } 0204 0205 // following two are really just xbel 0206 0207 QString GaleonImportCommand::requestFilename() const 0208 { 0209 return QFileDialog::getOpenFileName(KEBApp::self(), 0210 QString(), 0211 QString(QDir::homePath() + QStringLiteral("/.galeon")), 0212 i18n("Galeon Bookmark Files (*.xbel)")); 0213 } 0214 0215 QString KDE2ImportCommand::requestFilename() const 0216 { 0217 return QFileDialog::getOpenFileName(KEBApp::self(), 0218 QString(), 0219 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/konqueror"), 0220 i18n("KDE Bookmark Files (*.xml)")); 0221 } 0222 0223 /* -------------------------------------- */ 0224 0225 static void parseInto(const KBookmarkGroup &bkGroup, BookmarkImporterBase *importer) 0226 { 0227 BookmarkDomBuilder builder(bkGroup); 0228 builder.connectImporter(importer); 0229 importer->parse(); 0230 } 0231 0232 void OperaImportCommand::doExecute(const KBookmarkGroup &bkGroup) 0233 { 0234 OperaBookmarkImporterImpl importer; 0235 importer.setFilename(m_fileName); 0236 parseInto(bkGroup, &importer); 0237 } 0238 0239 void IEImportCommand::doExecute(const KBookmarkGroup &bkGroup) 0240 { 0241 IEBookmarkImporterImpl importer; 0242 importer.setFilename(m_fileName); 0243 parseInto(bkGroup, &importer); 0244 } 0245 0246 void HTMLImportCommand::doExecute(const KBookmarkGroup &bkGroup) 0247 { 0248 NSBookmarkImporterImpl importer; 0249 importer.setFilename(m_fileName); 0250 importer.setUtf8(m_utf8); 0251 parseInto(bkGroup, &importer); 0252 } 0253 0254 /* -------------------------------------- */ 0255 0256 void XBELImportCommand::doCreateHoldingFolder(KBookmarkGroup &) 0257 { 0258 // rather than reuse the old group node we transform the 0259 // root xbel node into the group when doing an xbel import 0260 } 0261 0262 void XBELImportCommand::doExecute(const KBookmarkGroup & /*bkGroup*/) 0263 { 0264 // check if already open first??? 0265 KBookmarkManager pManager(m_fileName); 0266 0267 QDomDocument doc = GlobalBookmarkManager::self()->mgr()->internalDocument(); 0268 0269 // get the xbel 0270 QDomNode subDoc = pManager.internalDocument().namedItem(QStringLiteral("xbel")).cloneNode(); 0271 if (subDoc.isProcessingInstruction()) 0272 subDoc = subDoc.nextSibling(); 0273 if (subDoc.isDocumentType()) 0274 subDoc = subDoc.nextSibling(); 0275 if (subDoc.nodeName() != QLatin1String("xbel")) 0276 return; 0277 0278 if (!folder().isEmpty()) { 0279 // transform into folder 0280 subDoc.toElement().setTagName(QStringLiteral("folder")); 0281 0282 // clear attributes 0283 QStringList tags; 0284 for (int i = 0; i < subDoc.attributes().count(); i++) 0285 tags << subDoc.attributes().item(i).toAttr().name(); 0286 for (QStringList::const_iterator it = tags.constBegin(); it != tags.constEnd(); ++it) 0287 subDoc.attributes().removeNamedItem((*it)); 0288 0289 subDoc.toElement().setAttribute(QStringLiteral("icon"), m_icon); 0290 0291 // give the folder a name 0292 QDomElement textElem = doc.createElement(QStringLiteral("title")); 0293 subDoc.insertBefore(textElem, subDoc.firstChild()); 0294 textElem.appendChild(doc.createTextNode(folder())); 0295 } 0296 0297 // import and add it 0298 QDomNode node = doc.importNode(subDoc, true); 0299 0300 if (!folder().isEmpty()) { 0301 GlobalBookmarkManager::self()->root().internalElement().appendChild(node); 0302 m_group = KBookmarkGroup(node.toElement()).address(); 0303 0304 } else { 0305 QDomElement root = GlobalBookmarkManager::self()->root().internalElement(); 0306 0307 QList<QDomElement> childList; 0308 0309 QDomNode n = subDoc.firstChild().toElement(); 0310 while (!n.isNull()) { 0311 QDomElement e = n.toElement(); 0312 if (!e.isNull()) 0313 childList.append(e); 0314 n = n.nextSibling(); 0315 } 0316 0317 QList<QDomElement>::Iterator it = childList.begin(); 0318 QList<QDomElement>::Iterator end = childList.end(); 0319 for (; it != end; ++it) 0320 root.appendChild((*it)); 0321 } 0322 } 0323 0324 #include "moc_importers.cpp"