mainwindow.cpp 8.58 KB
Newer Older
1 2 3
/*
 * ark -- archiver for the KDE project
 *
4
 * Copyright (C) 2002-2003: Georg Robbers <Georg.Robbers@urz.uni-hd.de>
5 6 7
 * Copyright (C) 2003: Helio Chissini de Castro <helio@conectiva.com>
 * Copyright (C) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
 * Copyright (C) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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.
 *
 */
24
#include "logging.h"
Henrique Pinto's avatar
Henrique Pinto committed
25
#include "mainwindow.h"
26
#include "kerfuffle/archive_kerfuffle.h"
27
#include "part/interface.h"
Henrique Pinto's avatar
Henrique Pinto committed
28

29
#include <KPluginFactory>
Henrique Pinto's avatar
Henrique Pinto committed
30
#include <KMessageBox>
31
#include <KLocalizedString>
Henrique Pinto's avatar
Henrique Pinto committed
32 33
#include <KActionCollection>
#include <KStandardAction>
34
#include <KRecentFilesAction>
35 36
#include <KEditToolBar>
#include <KShortcutsDialog>
Bhushan Shah's avatar
Bhushan Shah committed
37
#include <KService>
38
#include <KSharedConfig>
Bhushan Shah's avatar
Bhushan Shah committed
39
#include <KConfigGroup>
40
#include <KXMLGUIFactory>
Henrique Pinto's avatar
Henrique Pinto committed
41

42
#include <QDebug>
43 44
#include <QDragEnterEvent>
#include <QDragMoveEvent>
Lukáš Tinkl's avatar
Lukáš Tinkl committed
45 46
#include <QFileDialog>
#include <QMimeData>
47
#include <QPointer>
48

49 50
static bool isValidArchiveDrag(const QMimeData *data)
{
51
    return ((data->hasUrls()) && (data->urls().count() == 1));
52 53
}

54 55
MainWindow::MainWindow(QWidget *)
        : KParts::MainWindow()
Henrique Pinto's avatar
Henrique Pinto committed
56
{
57
    setXMLFile(QLatin1String( "arkui.rc" ));
Henrique Pinto's avatar
Henrique Pinto committed
58

59 60
    setupActions();
    statusBar();
Henrique Pinto's avatar
Henrique Pinto committed
61

62 63
    resize(640, 480);

64
    setAutoSaveSettings(QLatin1String( "MainWindow" ));
65

66
    setAcceptDrops(true);
Henrique Pinto's avatar
Henrique Pinto committed
67 68 69 70
}

MainWindow::~MainWindow()
{
71
    if (m_recentFilesAction) {
Laurent Montel's avatar
Laurent Montel committed
72
        m_recentFilesAction->saveEntries(KSharedConfig::openConfig()->group("Recent Files"));
73
    }
74 75

    guiFactory()->removeClient(m_part);
76 77
    delete m_part;
    m_part = 0;
Henrique Pinto's avatar
Henrique Pinto committed
78 79
}

80
void MainWindow::dragEnterEvent(QDragEnterEvent * event)
81
{
82
    qCDebug(ARK) << "dragEnterEvent" << event;
83

84
    Interface *iface = qobject_cast<Interface*>(m_part);
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
85 86 87
    if (iface->isBusy()) {
        return;
    }
88

Lukáš Tinkl's avatar
Lukáš Tinkl committed
89
    if (!event->source() && isValidArchiveDrag(event->mimeData())) {
90
        event->acceptProposedAction();
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
91
    }
92
    return;
93 94
}

95
void MainWindow::dropEvent(QDropEvent * event)
96
{
97
    qCDebug(ARK) << "dropEvent" << event;
98

99
    Interface *iface = qobject_cast<Interface*>(m_part);
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
100 101 102
    if (iface->isBusy()) {
        return;
    }
103

Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
104 105
    if ((event->source() == NULL) &&
        (isValidArchiveDrag(event->mimeData()))) {
106
        event->acceptProposedAction();
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
107
    }
108 109 110 111

    //TODO: if this call provokes a message box the drag will still be going
    //while the box is onscreen. looks buggy, do something about it
    openUrl(event->mimeData()->urls().at(0));
112 113
}

114
void MainWindow::dragMoveEvent(QDragMoveEvent * event)
115
{
116
    //qCDebug(ARK) << "dragMoveEvent" << event;
117

118
    Interface *iface = qobject_cast<Interface*>(m_part);
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
119 120 121
    if (iface->isBusy()) {
        return;
    }
122

Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
123 124
    if ((event->source() == NULL) &&
        (isValidArchiveDrag(event->mimeData()))) {
125
        event->acceptProposedAction();
Raphael Kubo da Costa's avatar
Raphael Kubo da Costa committed
126
    }
127 128
}

129 130
bool MainWindow::loadPart()
{
Bhushan Shah's avatar
Bhushan Shah committed
131 132 133 134 135 136 137
//    KPluginLoader loader(QLatin1String( "arkpart" ));
//    KPluginFactory *factory = loader.factory();
//    if (factory) {
//        m_part = static_cast<KParts::ReadWritePart*>(factory->create<KParts::ReadWritePart>(this));
//    }
//    if (!factory || !m_part) {
//        KMessageBox::error(this, i18n("Unable to find Ark's KPart component, please check your installation."));
Laurent Montel's avatar
Laurent Montel committed
138
//        qWarning() << "Error loading Ark KPart: " << loader.errorString();
Bhushan Shah's avatar
Bhushan Shah committed
139 140 141 142 143 144 145 146
//        return false;
//    }

    KPluginFactory *factory = 0;
    KService::Ptr service = KService::serviceByDesktopName(QLatin1String("ark_part"));

    if (service) {
        factory = KPluginLoader(service->library()).factory();
147
    }
Bhushan Shah's avatar
Bhushan Shah committed
148 149 150 151

    m_part = factory ? static_cast<KParts::ReadWritePart*>(factory->create<KParts::ReadWritePart>(this)) : 0;

    if (!m_part) {
152
        KMessageBox::error(this, i18n("Unable to find Ark's KPart component, please check your installation."));
153
        qCWarning(ARK) << "Error loading Ark KPart.";
154 155
        return false;
    }
156

Bhushan Shah's avatar
Bhushan Shah committed
157

Laurent Montel's avatar
Laurent Montel committed
158
    m_part->setObjectName( QLatin1String("ArkPart" ));
159 160
    setCentralWidget(m_part->widget());
    createGUI(m_part);
161

162 163
    connect(m_part, SIGNAL(busy()), this, SLOT(updateActions()));
    connect(m_part, SIGNAL(ready()), this, SLOT(updateActions()));
164
    connect(m_part, SIGNAL(quit()), this, SLOT(quit()));
165

166
    return true;
167 168
}

Henrique Pinto's avatar
Henrique Pinto committed
169 170
void MainWindow::setupActions()
{
171 172 173
    m_newAction = KStandardAction::openNew(this, SLOT(newArchive()), actionCollection());
    m_openAction = KStandardAction::open(this, SLOT(openArchive()), actionCollection());
    KStandardAction::quit(this, SLOT(quit()), actionCollection());
174

Lukáš Tinkl's avatar
Lukáš Tinkl committed
175
    m_recentFilesAction = KStandardAction::openRecent(this, SLOT(openUrl(QUrl)), actionCollection());
176 177 178 179 180
    m_recentFilesAction->setToolBarMode(KRecentFilesAction::MenuMode);
    m_recentFilesAction->setToolButtonPopupMode(QToolButton::DelayedPopup);
    m_recentFilesAction->setIconText(i18nc("action, to open an archive", "Open"));
    m_recentFilesAction->setStatusTip(i18n("Click to open an archive, click and hold to open a recently-opened archive"));
    m_recentFilesAction->setToolTip(i18n("Open an archive"));
Laurent Montel's avatar
Laurent Montel committed
181
    m_recentFilesAction->loadEntries(KSharedConfig::openConfig()->group("Recent Files"));
182 183
    connect(m_recentFilesAction, SIGNAL(triggered()),
            this, SLOT(openArchive()));
184

185
    createStandardStatusBarAction();
186

187 188
    KStandardAction::configureToolbars(this, SLOT(editToolbars()), actionCollection());
    KStandardAction::keyBindings(this, SLOT(editKeyBindings()), actionCollection());
189 190
}

191 192
void MainWindow::updateActions()
{
193 194 195 196
    Interface *iface = qobject_cast<Interface*>(m_part);
    m_newAction->setEnabled(!iface->isBusy());
    m_openAction->setEnabled(!iface->isBusy());
    m_recentFilesAction->setEnabled(!iface->isBusy());
197 198
}

199 200
void MainWindow::editKeyBindings()
{
201 202 203
    KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this);
    dlg.addCollection(actionCollection());
    dlg.addCollection(m_part->actionCollection());
204

205
    dlg.configure();
206 207 208 209
}

void MainWindow::editToolbars()
{
Bhushan Shah's avatar
Bhushan Shah committed
210 211
    KConfigGroup cfg(KSharedConfig::openConfig(), "MainWindow");
    saveMainWindowSettings(cfg);
212

213
    QPointer<KEditToolBar> dlg = new KEditToolBar(factory(), this);
214
    dlg.data()->exec();
215

216
    createGUI(m_part);
217

Bhushan Shah's avatar
Bhushan Shah committed
218
    applyMainWindowSettings(KSharedConfig::openConfig()->group(QLatin1String("MainWindow")));
219

220
    delete dlg.data();
Henrique Pinto's avatar
Henrique Pinto committed
221 222 223 224
}

void MainWindow::openArchive()
{
225 226
    Interface *iface = qobject_cast<Interface*>(m_part);
    Q_ASSERT(iface);
227
    Q_UNUSED(iface);
Lukáš Tinkl's avatar
Lukáš Tinkl committed
228 229 230 231 232 233 234 235

    QFileDialog dlg(this, i18nc("to open an archive", "Open Archive"));
    dlg.setMimeTypeFilters(Kerfuffle::supportedMimeTypes());
    dlg.setFileMode(QFileDialog::ExistingFile);
    dlg.setAcceptMode(QFileDialog::AcceptOpen);
    if (dlg.exec() == QDialog::Accepted) {
        openUrl(dlg.selectedUrls().first());
    }
236
}
Henrique Pinto's avatar
Henrique Pinto committed
237

Lukáš Tinkl's avatar
Lukáš Tinkl committed
238
void MainWindow::openUrl(const QUrl& url)
239
{
240 241
    if (!url.isEmpty()) {
        m_part->setArguments(m_openArgs);
242

243 244 245 246 247 248
        if (m_part->openUrl(url)) {
            m_recentFilesAction->addUrl(url);
        } else {
            m_recentFilesAction->removeUrl(url);
        }
    }
Henrique Pinto's avatar
Henrique Pinto committed
249 250
}

251 252
void MainWindow::setShowExtractDialog(bool option)
{
253
    if (option) {
254
        m_openArgs.metaData()[QLatin1String( "showExtractDialog" )] = QLatin1String( "true" );
255
    } else {
256
        m_openArgs.metaData().remove(QLatin1String( "showExtractDialog" ));
257
    }
258 259
}

Henrique Pinto's avatar
Henrique Pinto committed
260 261
void MainWindow::quit()
{
262
    close();
263 264 265 266
}

void MainWindow::newArchive()
{
267 268
    qCDebug(ARK) << "Creating new archive";

269 270
    Interface *iface = qobject_cast<Interface*>(m_part);
    Q_ASSERT(iface);
271
    Q_UNUSED(iface);
Raphael Kubo da Costa's avatar
const++  
Raphael Kubo da Costa committed
272 273

    const QStringList mimeTypes = Kerfuffle::supportedWriteMimeTypes();
274

275
    // qCDebug(ARK) << "Supported mimetypes are" << mimeTypes.join( QLatin1String(" "));
276

Lukáš Tinkl's avatar
Lukáš Tinkl committed
277 278
    QFileDialog dlg(this);
    dlg.setMimeTypeFilters(mimeTypes);
Ragnar Thomsen's avatar
Ragnar Thomsen committed
279
    dlg.setFileMode(QFileDialog::AnyFile);
Lukáš Tinkl's avatar
Lukáš Tinkl committed
280 281 282 283 284 285 286
    dlg.setAcceptMode(QFileDialog::AcceptSave);
    if (dlg.exec() == QDialog::Accepted) {
        m_openArgs.metaData()[QLatin1String( "createNewArchive" )] = QLatin1String( "true" );
        openUrl(dlg.selectedUrls().first());
        m_openArgs.metaData().remove(QLatin1String( "showExtractDialog" ));
        m_openArgs.metaData().remove(QLatin1String( "createNewArchive" ));
    }
Henrique Pinto's avatar
Henrique Pinto committed
287
}