diff --git a/krita/sketch/MainWindow.cpp b/krita/sketch/MainWindow.cpp index 80ac98670bb..d354674fdd4 100644 --- a/krita/sketch/MainWindow.cpp +++ b/krita/sketch/MainWindow.cpp @@ -1,254 +1,253 @@ /* This file is part of the KDE project * Copyright (C) 2012 Arjen Hiemstra * Copyright (C) 2012 KO GmbH. Contact: Boudewijn Rempt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MainWindow.h" #include "opengl/kis_opengl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "filter/kis_filter.h" #include "filter/kis_filter_registry.h" #include "kis_paintop.h" #include "kis_paintop_registry.h" #include #include #include "KisViewManager.h" #include #include "kis_config.h" #include #include "SketchDeclarativeView.h" #include "RecentFileManager.h" #include "DocumentManager.h" #include "QmlGlobalEngine.h" #include "Settings.h" class MainWindow::Private { public: Private(MainWindow* qq) : q(qq) , allowClose(true) , viewManager(0) { centerer = new QTimer(q); centerer->setInterval(10); centerer->setSingleShot(true); connect(centerer, SIGNAL(timeout()), q, SLOT(adjustZoomOnDocumentChangedAndStuff())); } MainWindow* q; bool allowClose; KisViewManager* viewManager; QString currentSketchPage; QTimer *centerer; }; MainWindow::MainWindow(QStringList fileNames, QWidget* parent, Qt::WindowFlags flags) : QMainWindow(parent, flags ), d( new Private(this)) { qApp->setActiveWindow(this); setWindowTitle(i18n("Krita Sketch")); setWindowIcon(KisIconUtils::loadIcon("kritasketch")); // Load filters and other plugins in the gui thread Q_UNUSED(KisFilterRegistry::instance()); Q_UNUSED(KisPaintOpRegistry::instance()); KisConfig cfg; cfg.setNewCursorStyle(CURSOR_STYLE_NO_CURSOR); cfg.setNewOutlineStyle(OUTLINE_NONE); cfg.setUseOpenGL(true); foreach(QString fileName, fileNames) { DocumentManager::instance()->recentFileManager()->addRecent(fileName); } connect(DocumentManager::instance(), SIGNAL(documentChanged()), SLOT(resetWindowTitle())); connect(DocumentManager::instance(), SIGNAL(documentSaved()), SLOT(resetWindowTitle())); QDeclarativeView* view = new SketchDeclarativeView(); QmlGlobalEngine::instance()->setEngine(view->engine()); view->engine()->rootContext()->setContextProperty("mainWindow", this); #ifdef Q_OS_WIN QDir appdir(qApp->applicationDirPath()); // Corrects for mismatched case errors in path (qtdeclarative fails to load) wchar_t buffer[1024]; QString absolute = appdir.absolutePath(); DWORD rv = ::GetShortPathName((wchar_t*)absolute.utf16(), buffer, 1024); rv = ::GetLongPathName(buffer, buffer, 1024); QString correctedPath((QChar *)buffer); appdir.setPath(correctedPath); // for now, the app in bin/ and we still use the env.bat script appdir.cdUp(); view->engine()->addImportPath(appdir.canonicalPath() + "/lib/calligra/imports"); view->engine()->addImportPath(appdir.canonicalPath() + "/lib64/calligra/imports"); QString mainqml = appdir.canonicalPath() + "/share/apps/kritasketch/kritasketch.qml"; #else const QStringList qmlImportDirs = KGlobal::dirs()->findDirs("lib", "calligra/imports"); foreach(const QString &dir, qmlImportDirs) { view->engine()->addImportPath(dir); } // QString mainqml = KGlobal::dirs()->findResource("data", "kritasketch/kritasketch.qml"); QString mainqml = KoResourcePaths::findResource("data", "kritasketch/kritasketch.qml"); #endif Q_ASSERT(QFile::exists(mainqml)); if (!QFile::exists(mainqml)) { QMessageBox::warning(0, i18nc("@title:window", "No QML found"), mainqml + " doesn't exist."); } QFileInfo fi(mainqml); view->setSource(QUrl::fromLocalFile(fi.canonicalFilePath())); view->setResizeMode( QDeclarativeView::SizeRootObjectToView ); if (view->errors().count() > 0) { foreach(const QDeclarativeError &error, view->errors()) { dbgKrita << error.toString(); } } setCentralWidget(view); } void MainWindow::resetWindowTitle() { - QUrl url(DocumentManager::instance()->settingsManager()->currentFile()); - QString fileName = url.fileName(); - if(url.scheme() == "temp") - fileName = i18n("Untitled"); + const QString currentFile = DocumentManager::instance()->settingsManager()->currentFile(); + const QString fileName = + currentFile.startsWith(QLatin1String("temp://")) ? i18n("Untitled") : QFileInfo(currentFile).fileName(); KoDialog::CaptionFlags flags = KoDialog::HIGCompliantCaption; KisDocument* document = DocumentManager::instance()->document(); if (document && document->isModified() ) { flags |= KoDialog::ModifiedCaption; } setWindowTitle( KoDialog::makeStandardCaption(fileName, this, flags) ); } bool MainWindow::allowClose() const { return d->allowClose; } void MainWindow::setAllowClose(bool allow) { d->allowClose = allow; } QString MainWindow::currentSketchPage() const { return d->currentSketchPage; } void MainWindow::setCurrentSketchPage(QString newPage) { d->currentSketchPage = newPage; emit currentSketchPageChanged(); } void MainWindow::adjustZoomOnDocumentChangedAndStuff() { if (d->viewManager) { qApp->processEvents(); d->viewManager->zoomController()->setZoom(KoZoomMode::ZOOM_PAGE, 1.0); qApp->processEvents(); QPoint center = d->viewManager->canvas()->rect().center(); static_cast(d->viewManager->canvasBase()->canvasController())->zoomRelativeToPoint(center, 0.9); qApp->processEvents(); } } QObject* MainWindow::sketchKisView() const { return d->viewManager; } void MainWindow::setSketchKisView(QObject* newView) { if (d->viewManager) d->viewManager->disconnect(this); if (d->viewManager != newView) { d->viewManager = qobject_cast(newView); connect(d->viewManager, SIGNAL(sigLoadingFinished()), d->centerer, SLOT(start())); d->centerer->start(); emit sketchKisViewChanged(); } } void MainWindow::minimize() { setWindowState(windowState() ^ Qt::WindowMinimized); } void MainWindow::closeWindow() { //For some reason, close() does not work even if setAllowClose(true) was called just before this method. //So instead just completely quit the application, since we are using a single window anyway. QApplication::exit(); } void MainWindow::resizeEvent(QResizeEvent* event) { // TODO this needs setting somewhere... // d->constants->setGridWidth( event->size().width() / d->constants->gridColumns() ); // d->constants->setGridHeight( event->size().height() / d->constants->gridRows() ); QWidget::resizeEvent(event); } void MainWindow::closeEvent(QCloseEvent* event) { if (!d->allowClose) { event->ignore(); emit closeRequested(); } else { event->accept(); } } MainWindow::~MainWindow() { delete d; } diff --git a/krita/sketch/qml/MainPage.qml b/krita/sketch/qml/MainPage.qml index 35d7df4bcae..4ee919c655f 100644 --- a/krita/sketch/qml/MainPage.qml +++ b/krita/sketch/qml/MainPage.qml @@ -1,386 +1,386 @@ /* This file is part of the KDE project * Copyright (C) 2012 Arjen Hiemstra * * 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. */ import QtQuick 1.1 import org.krita.sketch 1.0 import org.krita.sketch.components 1.0 import "panels" Page { property string pageName: "MainPage"; SketchView { id: sketchView; width: parent.width; height: parent.height; file: Settings.currentFile; onInteractionStarted: { panelBar.collapse(); Krita.VirtualKeyboardController.requestHideKeyboard(); } onLoadingFinished: { loadingDialog.hide("Done!"); savingDialog.hide("Done!"); } onSavingFinished: { loadingDialog.hide("Done!"); savingDialog.hide("Done!"); if (d.saveRequested) { d.loadNewFile(); } if (d.closeRequested) { d.closeWindow(); } } onProgress: { if (value === -1 || value === 100) { loadingDialog.hide("Done!"); savingDialog.hide("Done!"); } loadingDialog.progress = value; savingDialog.progress = value; } onViewChanged: if (window.sketchKisView !== undefined) { window.sketchKisView = view; } } Connections { target: window; onSwitchedToSketch: sketchView.activate(); } ToolManager { id: toolManager; view: sketchView.view; } LayerModel { id: layerModel; // Notice - the model needs to know about the engine before the view, hence it is set first // This could be rectified, but for now know that the order here is important. engine: QMLEngine; view: sketchView.view; } PanelBar { id: panelBar; panelHeight: parent.height; width: parent.width; } NewImagePanel { id: newPanel; anchors.left: parent.left; width: Constants.GridWidth * 4; height: parent.height; onClicked: d.beginCreateNewFile(options); } OpenImagePanel { id: openPanel; anchors.left: parent.left; width: Constants.GridWidth * 4; height: parent.height; onClicked: d.beginOpenFile(file); } MenuPanel { id: menuPanel; anchors.bottom: parent.bottom; width: parent.width; z: 10; newButtonChecked: !newPanel.collapsed; openButtonChecked: !openPanel.collapsed; onCollapsedChanged: if ( collapsed ) { newPanel.collapsed = true; openPanel.collapsed = true; } onButtonClicked: { switch( button ) { case "new": { d.previousFile = Settings.currentFile; newPanel.collapsed = !newPanel.collapsed; openPanel.collapsed = true; } case "open": { d.previousFile = Settings.currentFile; openPanel.collapsed = !openPanel.collapsed; newPanel.collapsed = true; } case "save": if (!Settings.temporaryFile) { savingDialog.show("Saving file..."); sketchView.save(); } else { pageStack.push( saveAsPage, { view: sketchView } ); } case "saveAs": pageStack.push( saveAsPage, { view: sketchView } ); case "settings": pageStack.push( settingsPage ); case "help": pageStack.push( helpPage ); case "undo": sketchView.undo(); case "redo": sketchView.redo(); case "minimize": Krita.Window.minimize(); case "close": Krita.Window.close(); case "zoomIn": sketchView.zoomIn(); case "zoomOut": sketchView.zoomOut(); case "switchToDesktop": switchToDesktopAction.trigger(); } } } MessageStack { id: messageStack; anchors { horizontalCenter: parent.horizontalCenter; bottom: menuPanel.top; bottomMargin: Constants.GridHeight; } Connections { target: sketchView; onFloatingMessageRequested: { if(message == undefined || message.startsWith == undefined) return; if(message.startsWith("Zoom") || message.startsWith("Rotation")) return; messageStack.showMessage(message, iconName); } } } ToolOverlayPanel { id: toolOverlay; anchors { left: menuPanel.left; leftMargin: (Constants.IsLandscape ? Constants.GridWidth * 4: Constants.GridWidth * 2) + Constants.DefaultMargin; right: menuPanel.right; rightMargin: (Constants.IsLandscape ? 0 : Constants.GridWidth * 2) + Constants.DefaultMargin; bottom: menuPanel.top; bottomMargin: Constants.DefaultMargin; } } Dialog { id: loadingDialog; title: "Loading"; message: "Please wait..."; textAlign: Text.AlignHCenter; progress: 0; modalBackgroundColor: "#ffffff"; } Dialog { id: savingDialog; title: "Saving"; message: "Please wait..."; textAlign: Text.AlignHCenter; modalBackgroundColor: "#ffffff"; } Dialog { id: progressDialog; title: Krita.ProgressProxy.taskName != "" ? Krita.ProgressProxy.taskName : "Applying..."; } Dialog { id: modifiedDialog; title: "Image was modified"; message: "The image was modified. Do you want to save your changes?"; buttons: [ "Save", "Discard", "Cancel" ]; onButtonClicked: { switch(button) { case 0: { if (Settings.temporaryFile) { d.saveRequested = true; pageStack.push( saveAsPage, { view: sketchView, updateCurrentFile: false } ); } else { savingDialog.show("Please wait..."); sketchView.save(); if (d.closeRequested) { d.closeWindow(); } else { d.loadNewFile(); } } } case 1: { if (d.closeRequested) { d.closeWindow(); } else { d.loadNewFile(); } } default: { Settings.currentFile = d.previousFile; d.saveRequested = false; d.closeRequested = false; } } } onCanceled: { Settings.currentFile = d.previousFile; d.saveRequested = false; d.closeRequested = false; } } Connections { target: Krita.ProgressProxy; onTaskStarted: progressDialog.show(); onTaskEnded: progressDialog.hide(); onValueChanged: progressDialog.progress = value; } Connections { target: Settings; onTemporaryFileChanged: if (window.temporaryFile !== undefined) window.temporaryFile = Settings.temporaryFile; } Connections { target: Krita.Window; onCloseRequested: { if (sketchView.modified) { d.closeRequested = true; modifiedDialog.show(); } else { d.closeWindow(); } } } Component.onCompleted: { Krita.Window.allowClose = false; loadingDialog.show("Please wait..."); - if(Settings.currentFile.indexOf("temp") == -1) { + if(Settings.currentFile.indexOf("temp://") !== 0) { sketchView.file = Settings.currentFile; } } Component { id: openImagePage; OpenImagePage { onFinished: { pageStack.pop(); d.beginOpenFile(file); } } } Component { id: settingsPage; SettingsPage { } } Component { id: helpPage; HelpPage { } } Component { id: saveAsPage; SaveImagePage { onFinished: { pageStack.pop(); d.saveFileAs(file, type); } } } Component { id: customImagePage; CustomImagePage { onFinished: { pageStack.pop(); d.beginCreateNewFile(options); } } } QtObject { id: d; property string previousFile; property bool closeRequested; property bool saveRequested; property variant newFileOptions; property string fileToOpen; function beginCreateNewFile(options) { if(options !== undefined) { newFileOptions = options; if (sketchView.modified) { modifiedDialog.show(); } else { d.loadNewFile(); } } else { pageStack.push(customImagePage); } } function beginOpenFile(file) { if(!Settings.temporaryFile && file === sketchView.file) return; if(file !== "") { fileToOpen = file; if(sketchView.modified) { modifiedDialog.show(); } else { d.loadNewFile(); } } else { pageStack.push(openImagePage); } } function loadNewFile() { saveRequested = false; loadingDialog.progress = 0; if(newFileOptions !== undefined) { loadingDialog.show("Creating new image..."); if(newFileOptions.template !== undefined) { Settings.currentFile = Krita.ImageBuilder.createImageFromTemplate(newFileOptions); settings.temporaryFile = true; } else if(newFileOptions.source === undefined) { Settings.currentFile = Krita.ImageBuilder.createBlankImage(newFileOptions); Settings.temporaryFile = true; } else if(newFileOptions.source == "clipboard") { Settings.currentFile = Krita.ImageBuilder.createImageFromClipboard(); Settings.temporaryFile = true; } } else { loadingDialog.show("Loading " + fileToOpen); Settings.currentFile = fileToOpen; sketchView.file = Settings.currentFile; } menuPanel.collapsed = true; fileToOpen = ""; newFileOptions = null; } function saveFileAs(file, type) { savingDialog.show("Saving image to " + file); sketchView.saveAs( file, type ); Settings.temporaryFile = false; } function closeWindow() { Krita.Window.allowClose = true; Krita.Window.closeWindow(); } } }