/* * Copyright 2008 Ben Boeckel * * 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 3 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, see . */ // Header include #include "PokeModrUI.h" // PokeModr includes #include "ObjectUI.h" #include "PokemodTreeModel.h" // Pokemod includes #include "../pokemod/Pokemod.h" // Qt includes #include #include // KDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include PokeModrUI::PokeModrUI(KConfigGroup config, KConfigGroup history, QWidget* parent) : KMainWindow(parent), m_config(config), m_recent(new KRecentFilesAction("&Recent Files...", this)) { setupUi(this); QMetaObject::connectSlotsByName(this); m_recent->loadEntries(history); // TODO: Somehow get KAction/KMenus into the ui files KMenuBar* menubar = new KMenuBar(this); KMenu* menuFile = new KMenu("&File", menubar); menuFile->addAction(KStandardAction::openNew(this, SLOT(newPokemod()), menuFile)); menuFile->addAction(KStandardAction::open(this, SLOT(openPokemod()), menuFile)); menuFile->addAction(KStandardAction::openRecent(this, SLOT(openPokemod(const KUrl&)), menuFile)); menuFile->addSeparator(); menuFile->addAction(KStandardAction::save(this, SLOT(savePokemod()), menuFile)); menuFile->addAction(KStandardAction::saveAs(this, SLOT(saveAsPokemod()), menuFile)); menuFile->addSeparator(); menuFile->addAction(KStandardAction::quit(this, SLOT(quit()), menuFile)); menubar->addMenu(menuFile); KMenu* menuEdit = new KMenu("&Edit", menubar); menuEdit->addAction(KStandardAction::cut(menuEdit)); menuEdit->addAction(KStandardAction::copy(menuEdit)); menuEdit->addAction(KStandardAction::paste(menuEdit)); menuEdit->addSeparator(); KAction* menuCut = new KAction(KIcon("edit-cut"), "Cu&t Object", menuEdit); menuCut->setShortcut(KShortcut("Alt+X")); menuEdit->addAction(menuCut); connect(menuCut, SIGNAL(triggered()), this, SLOT(cutObject())); KAction* menuCopy = new KAction(KIcon("edit-copy"), "Cop&y Object", menuEdit); menuCopy->setShortcut(KShortcut("Alt+C")); menuEdit->addAction(menuCopy); connect(menuCopy, SIGNAL(triggered()), this, SLOT(copyObject())); KAction* menuPaste = new KAction(KIcon("edit-paste"), "Past&e Object", menuEdit); menuPaste->setShortcut(KShortcut("Alt+V")); menuEdit->addAction(menuPaste); connect(menuPaste, SIGNAL(triggered()), this, SLOT(pasteObject())); menuEdit->addSeparator(); menuEdit->addAction(KStandardAction::preferences(this, SLOT(preferences()), menuEdit)); menubar->addMenu(menuEdit); menubar->addMenu(customHelpMenu(false)); setMenuBar(menubar); KToolBar* toolbar = new KToolBar("toolbar", this, Qt::TopToolBarArea, false, true, true); toolbar->addAction(KStandardAction::openNew(this, SLOT(newPokemod()), toolbar)); toolbar->addAction(KStandardAction::open(this, SLOT(openPokemod()), toolbar)); toolbar->addAction(KStandardAction::openRecent(this, SLOT(openPokemod(const KUrl&)), toolbar)); toolbar->addSeparator(); toolbar->addAction(KStandardAction::save(this, SLOT(savePokemod()), toolbar)); toolbar->addAction(KStandardAction::saveAs(this, SLOT(saveAsPokemod()), toolbar)); toolbar->addSeparator(); toolbar->addAction(KStandardAction::cut(toolbar)); toolbar->addAction(KStandardAction::copy(toolbar)); toolbar->addAction(KStandardAction::paste(toolbar)); toolbar->addSeparator(); KAction* toolbarCut = new KAction(KIcon("edit-cut"), "Cu&t Object", toolbar); toolbar->addAction(toolbarCut); connect(toolbarCut, SIGNAL(triggered()), this, SLOT(cutObject())); KAction* toolbarCopy = new KAction(KIcon("edit-copy"), "Cop&y Object", toolbar); toolbar->addAction(toolbarCopy); connect(toolbarCopy, SIGNAL(triggered()), this, SLOT(copyObject())); KAction* toolbarPaste = new KAction(KIcon("edit-paste"), "Past&e Object", toolbar); toolbar->addAction(toolbarPaste); connect(toolbarPaste, SIGNAL(triggered()), this, SLOT(pasteObject())); toolbar->addSeparator(); toolbar->addAction(KStandardAction::preferences(this, SLOT(preferences()), toolbar)); toolbar->addSeparator(); toolbar->addAction(KStandardAction::quit(this, SLOT(quit()), toolbar)); addToolBar(toolbar); splitter->setSizes(QList() << config.readEntry("treeWidth", 100) << config.readEntry("panelWidth", 100)); KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); if (args) { for(int i = 0; i < args->count(); ++i) openPokemod(args->url(i)); args->clear(); } if (config.readEntry("reloadOnStart", false)) { for (int i = 0; i < config.readEntry("openedFiles", 0); ++i) openPokemod(m_recent->urls().at(i)); } setAutoSaveSettings("MainWindow", true); treePokemod->setModel(new PokemodTreeModel(QStringList(), treePokemod)); connect(buttonApply, SIGNAL(clicked()), this, SLOT(update())); } PokeModrUI::~PokeModrUI() { // delete m_recent; // on_actionQuit_triggered(); } void PokeModrUI::update() { treePokemod->update(treePokemod->currentIndex()); } void PokeModrUI::closeEvent(QCloseEvent* event) { quit(); event->accept(); } void PokeModrUI::setChangedTitle(const bool changed) { setWindowTitle(QString::fromUtf8("%1%2 - PokéModr").arg(treePokemod->description(treePokemod->currentIndex())).arg(changed ? "*" : "")); } void PokeModrUI::newPokemod() { treePokemod->addPokemod(new Pokemod()); } void PokeModrUI::openPokemod() { QString path(KFileDialog::getOpenFileName(KUrl("kfiledialog:///pokemod"), QString::fromUtf8("*.pmod|PokéMod files"), this)); if (!path.isEmpty()) { if (openPokemod(path)) { m_recent->addUrl(path); m_recent->saveEntries(m_config); } } } void PokeModrUI::openPokemod(const KUrl& path) { if (path.isLocalFile()) openPokemod(path.path()); else { QString temp; if (KIO::NetAccess::download(path, temp, this)) { if (openPokemod(temp)) { m_recent->addUrl(path); m_recent->saveEntries(m_config); } KIO::NetAccess::removeTempFile(temp); } else KMessageBox::error(this, KIO::NetAccess::lastErrorString(), "KIO Error"); } } bool PokeModrUI::openPokemod(const QString& path) { QFile file(path); if (file.open(QIODevice::ReadOnly)) { QDomDocument xml; if (xml.setContent(&file)) { if (xml.doctype().name() == "Pokemod") { treePokemod->addPokemod(new Pokemod(xml.documentElement())); return true; } else KMessageBox::error(this, QString::fromUtf8("The file is not a PokéMod."), QString::fromUtf8("Invalid PokéMod")); } else KMessageBox::error(this, "The file is not a valid XML file.", QString::fromUtf8("Invalid PokéMod")); file.close(); } return false; } void PokeModrUI::savePokemod() { Object* object = static_cast(treePokemod->currentIndex().internalPointer()); treePokemod->savePokemod(static_cast(object->pokemod())); } void PokeModrUI::saveAsPokemod() { Object* object = static_cast(treePokemod->currentIndex().internalPointer()); KUrl url = KFileDialog::getSaveUrl(KUrl("kfiledialog:///pokemod"), QString::fromUtf8("*.pmod|PokéMod files"), this, QString::fromUtf8("Open PokéMod")); if (!url.isEmpty()) treePokemod->savePokemod(static_cast(object->pokemod()), url); } void PokeModrUI::closePokeMod() { // TODO: Close the Pokemod with the current editor open // if (formPanel->widget()) // { // ObjectUI* o = static_cast(formPanel->widget()); // const Pokemod* p = o->original()->pokemod(); // if (!o->close()) // return; // switch (KMessageBox::questionYesNoCancel(this, "You have unsaved changes, would you like to save them?", "Unsaved PokéMod")) // { // case KMessageBox::Yes: // on_actionSave_triggered(); // case KMessageBox::No: // break; // case KMessageBox::Cancel: // return; // } // for (QMutableListIterator i(m_pokemods); i.hasNext(); i.next()) // { // if (i.value() == p) // { // i.remove(); // break; // } // } // delete p; // } } void PokeModrUI::quit() { // TODO: clean up the tree // while (m_pokemods.size()) // closePokeMod(); // if (m_clipboard) // delete m_clipboard; close(); } void PokeModrUI::cutObject() { m_clipboard = treePokemod->cut(treePokemod->currentIndex()); } void PokeModrUI::copyObject() { m_clipboard = treePokemod->copy(treePokemod->currentIndex()); } void PokeModrUI::pasteObject() { treePokemod->paste(treePokemod->currentIndex(), m_clipboard); } void PokeModrUI::preferences() { // TODO: preferences } void PokeModrUI::on_splitter_splitterMoved() { m_config.writeEntry("treeWidth", splitter->sizes()[0]); m_config.writeEntry("panelWidth", splitter->sizes()[1]); } void PokeModrUI::on_treePokemod_clicked(const QModelIndex& index) { ObjectUI* widget = treePokemod->editorWidget(index); if (widget) { if (formPanel->widget()) { if (!static_cast(formPanel->widget())->close()) return; } boxButtons->setEnabled(false); connect(widget, SIGNAL(changed(bool)), this, SLOT(setChangedTitle(bool))); connect(widget, SIGNAL(changed(bool)), boxButtons, SLOT(setEnabled(bool))); connect(buttonApply, SIGNAL(clicked()), widget, SLOT(apply())); connect(buttonDiscard, SIGNAL(clicked()), widget, SLOT(discard())); setChangedTitle(false); formPanel->setWidget(widget); formPanel->show(); } } void PokeModrUI::on_treePokemod_customContextMenuRequested(const QPoint& position) { KMenu* menu = treePokemod->contextMenu(treePokemod->indexAt(position)); if (menu) menu->popup(mapToGlobal(position)); }