bool Editor::saveFile(const QUrl &targetUrl) { QUrl url(targetUrl); bool result = false; if (url.isEmpty() && currentUrl().isEmpty()) { result = saveFileAs(); } else { if (url.isEmpty()) url = currentUrl(); QTemporaryFile tmp; // only used for network export tmp.setAutoRemove(false); tmp.open(); QString filename = url.isLocalFile() ? url.toLocalFile() : tmp.fileName(); QSaveFile *savefile = new QSaveFile(filename); if (savefile->open(QIODevice::WriteOnly)) { QTextStream outputStream(savefile); // store commands in their generic @(...) notation format, to be translatable when reopened // this allows sharing of scripts written in different languages Tokenizer tokenizer; tokenizer.initialize(editor->document()->toPlainText()); const QStringList localizedLooks(Translator::instance()->allLocalizedLooks()); QString unstranslated; Token* t; bool pendingEOL = false; // to avoid writing a final EOL token while ((t = tokenizer.getToken())->type() != Token::EndOfInput) { if (pendingEOL) { unstranslated.append('\n'); pendingEOL = false; } if (localizedLooks.contains(t->look())) { QString defaultLook(Translator::instance()->defaultLook(t->look())); unstranslated.append(QString("@(%1)").arg(defaultLook)); } else { if (t->type() == Token::EndOfLine) pendingEOL = true; else unstranslated.append(t->look()); } } outputStream << KTURTLE_MAGIC_1_0 << '\n'; outputStream << unstranslated; outputStream.flush(); savefile->commit(); // check for error here? } delete savefile; if (!url.isLocalFile()) { KIO::StoredTransferJob *job = KIO::storedPut(savefile, url, -1, 0); if(job->exec()){ setCurrentUrl(url); editor->document()->setModified(false); // MainWindow will add us to the recent file list emit fileSaved(url); result = true; // fix GUI for saveAs and saveExamples. TODO: check 5 lines above } } } return result; }
void Editor::openExample(const QString& example, const QString& exampleName) { if (newFile()) { setContent(example); editor->document()->setModified(false); setCurrentUrl(QUrl::fromLocalFile(exampleName)); } }
bool Editor::newFile() { if (maybeSave()) { editor->document()->clear(); setCurrentUrl(); return true; } return false; }
Editor::Editor(QWidget *parent) : QFrame(parent) { setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); setLineWidth(CURSOR_WIDTH); setCurrentUrl(); currentRow = 1; currentCol = 1; // setup the main view editor = new TextEdit(this); editor->document()->setDefaultFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); editor->setFrameStyle(QFrame::NoFrame); editor->installEventFilter(this); editor->setLineWrapMode(QTextEdit::WidgetWidth); editor->setTabStopWidth(editor->fontMetrics().width("0") * TAB_WIDTH); editor->setAcceptRichText(false); setFocusProxy(editor); connect(editor->document(), &QTextDocument::contentsChange, this, &Editor::textChanged); connect(editor->document(), &QTextDocument::modificationChanged, this, &Editor::setModified); connect(editor, &TextEdit::cursorPositionChanged, this, &Editor::updateOnCursorPositionChange); // setup the line number pane numbers = new LineNumbers(this, editor); numbers->setFont(editor->document()->defaultFont()); numbers->setWidth(1); connect(editor->document()->documentLayout(), SIGNAL(update(const QRectF &)), numbers, SLOT(update())); connect(editor->verticalScrollBar(), SIGNAL(valueChanged(int)), numbers, SLOT(update())); // let the line numbers and the editor coexist box = new QHBoxLayout(this); box->setSpacing(0); box->setMargin(0); box->addWidget(numbers); box->addWidget(editor); // calculate the bg color for the highlighted line QColor bgColor = this->palette().brush(this->backgroundRole()).color(); highlightedLineBackgroundColor.setHsv( LINE_HIGHLIGHT_COLOR.hue(), bgColor.saturation() + EXTRA_SATURATION, bgColor.value()); // our syntax highlighter (this does not do any markings) highlighter = new Highlighter(editor->document()); // create a find dialog fdialog = new KFindDialog(); fdialog->setSupportsRegularExpressionFind(false); fdialog->setHasSelection(false); fdialog->setHasCursor(false); // sets some more default values newFile(); tokenizer = new Tokenizer(); }
bool MainWindow::closeFile() { if (maybeSave()) { disconnect(m_tikzEditorView, SIGNAL(contentsChanged()), m_tikzPreviewController, SLOT(regeneratePreviewAfterDelay())); m_tikzEditorView->editor()->clear(); connect(m_tikzEditorView, SIGNAL(contentsChanged()), m_tikzPreviewController, SLOT(regeneratePreviewAfterDelay())); setCurrentUrl(Url()); m_tikzPreviewController->emptyPreview(); // abort still running processes m_logTextEdit->updateLog(QString(), false); // clear log window m_mouseCoordinatesLabel->setText(QString()); return true; } return false; }
bool Editor::openFile(const QUrl &_url) { QUrl url = _url; if (maybeSave()) { if (url.isEmpty()) { url = QFileDialog::getOpenFileUrl(this, i18n("Open"), QUrl(), QString("%1 (*.turtle);;%2 (*)").arg(i18n("Turtle code files")).arg(i18n("All files")) ); } if (!url.isEmpty()) { KIO::StoredTransferJob *job = KIO::storedGet(url); if (job->exec()) { QByteArray data = job->data(); QBuffer buffer(&data); if (!buffer.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; // can't happen } QTextStream in(&buffer); // check for our magic identifier QString s; s = in.readLine(); if (s != KTURTLE_MAGIC_1_0) { KMessageBox::error(this, i18n("The file you try to open is not a valid KTurtle script, or is incompatible with this version of KTurtle.\nCannot open %1", url.toDisplayString(QUrl::PreferLocalFile))); return false; } QString localizedScript = Translator::instance()->localizeScript(in.readAll()); setContent(localizedScript); setCurrentUrl(url); editor->document()->setModified(false); emit fileOpened(url); return true; } else { KMessageBox::error(this, job->errorString()); return false; } } } // statusbar "Nothing opened" return false; }
MainWindow::MainWindow() { //QTime t = QTime::currentTime(); #ifndef KTIKZ_USE_KDE m_aboutDialog = 0; m_assistantController = 0; #endif m_configDialog = 0; m_isModifiedExternally = false; m_insertAction = 0; s_mainWindowList.append(this); #ifndef KTIKZ_USE_KDE QStringList themeSearchPaths; themeSearchPaths << QDir::homePath() + QLatin1String("/.local/share/icons/"); themeSearchPaths << QIcon::themeSearchPaths(); QIcon::setThemeSearchPaths(themeSearchPaths); #endif setAttribute(Qt::WA_DeleteOnClose); #ifdef KTIKZ_USE_KDE setObjectName(QLatin1String("ktikz#")); setWindowIcon(KIcon(QLatin1String("ktikz"))); Action::setActionCollection(actionCollection()); #else setObjectName(QLatin1String("qtikz#") + QString::number(s_mainWindowList.size())); setWindowIcon(QIcon(QLatin1String(":/icons/qtikz-22.png"))); #endif setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); //qCritical() << t.msecsTo(QTime::currentTime()); m_tikzPreviewController = new TikzPreviewController(this); //qCritical() << "TikzPreviewController" << t.msecsTo(QTime::currentTime()); m_tikzEditorView = new TikzEditorView(this); //qCritical() << "TikzEditorView" << t.msecsTo(QTime::currentTime()); m_commandInserter = new TikzCommandInserter(this); m_tikzHighlighter = new TikzHighlighter(m_tikzEditorView->editor()->document()); m_userCommandInserter = new UserCommandInserter(this); QWidget *mainWidget = new QWidget(this); QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); mainLayout->setSpacing(0); mainLayout->setMargin(0); mainLayout->addWidget(m_tikzPreviewController->templateWidget()); mainLayout->addWidget(m_tikzEditorView); m_logDock = new QDockWidget(this); m_logDock->setObjectName(QLatin1String("LogDock")); m_logDock->setAllowedAreas(Qt::AllDockWidgetAreas); m_logDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); m_logDock->setWindowTitle(tr("&Messages")); addDockWidget(Qt::BottomDockWidgetArea, m_logDock); m_logTextEdit = new LogTextEdit; m_logTextEdit->setWhatsThis(tr("<p>The messages produced by " "LaTeX are shown here. If your TikZ code contains errors, " "then a red border will appear and the errors will be " "highlighted.</p>")); m_logDock->setWidget(m_logTextEdit); m_previewDock = new QDockWidget(this); m_previewDock->setObjectName(QLatin1String("PreviewDock")); m_previewDock->setAllowedAreas(Qt::AllDockWidgetAreas); m_previewDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); m_previewDock->setWindowTitle(tr("Previe&w")); m_previewDock->setWidget(m_tikzPreviewController->tikzPreview()); addDockWidget(Qt::RightDockWidgetArea, m_previewDock); setCentralWidget(mainWidget); createActions(); #ifndef KTIKZ_USE_KDE createToolBars(); // run first in order to be able to add file/editToolBar->toggleViewAction() to the menu createMenus(); #endif //qCritical() << "createMenus" << t.msecsTo(QTime::currentTime()); createCommandInsertWidget(); // must happen after createMenus and before readSettings createStatusBar(); #ifdef KTIKZ_USE_KDE setupGUI(ToolBar | Keys | StatusBar | Save); setXMLFile(QLatin1String("ktikzui.rc")); createGUI(); guiFactory()->addClient(this); #endif setTabOrder(m_tikzPreviewController->templateWidget()->lastTabOrderWidget(), m_tikzEditorView->editor()); connect(m_commandInserter, SIGNAL(showStatusMessage(QString,int)), statusBar(), SLOT(showMessage(QString,int))); connect(m_tikzEditorView, SIGNAL(modificationChanged(bool)), this, SLOT(setDocumentModified(bool))); connect(m_tikzEditorView, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(showCursorPosition(int,int))); connect(m_tikzEditorView, SIGNAL(showStatusMessage(QString,int)), statusBar(), SLOT(showMessage(QString,int))); connect(m_tikzEditorView, SIGNAL(focusIn()), this, SLOT(checkForFileChanges())); connect(m_tikzEditorView, SIGNAL(focusOut()), this, SLOT(saveLastInternalModifiedDateTime())); connect(m_tikzPreviewController, SIGNAL(updateLog(QString,bool)), m_logTextEdit, SLOT(updateLog(QString,bool))); connect(m_tikzPreviewController, SIGNAL(appendLog(QString,bool)), m_logTextEdit, SLOT(appendLog(QString,bool))); connect(m_tikzPreviewController, SIGNAL(showMouseCoordinates(qreal,qreal,int,int)), this, SLOT(showMouseCoordinates(qreal,qreal,int,int))); connect(m_userCommandInserter, SIGNAL(updateCompleter()), this, SLOT(updateCompleter())); readSettings(); // must be run after defining tikzController and tikzHighlighter, and after creating the toolbars, and after the connects //qCritical() << "readSettings()" << t.msecsTo(QTime::currentTime()); setCurrentUrl(Url()); setDocumentModified(false); saveLastInternalModifiedDateTime(); m_tikzEditorView->editor()->setFocus(); // delayed initialization // QTimer::singleShot(0, this, SLOT(init())); // this causes flicker at startup and init() is not executed in a separate thread anyway :( init(); //qCritical() << "mainwindow" << t.msecsTo(QTime::currentTime()); }
KDirSelectDialog::KDirSelectDialog(const KUrl &startDir, bool localOnly, QWidget *parent) : KDialog( parent ), d( new Private( localOnly, this ) ) { setCaption( i18nc("@title:window","Select Folder") ); setButtons( Ok | Cancel | User1 ); setButtonGuiItem( User1, KGuiItem( i18nc("@action:button","New Folder..."), "folder-new" ) ); setDefaultButton(Ok); button(Ok)->setFocus(); QFrame *page = new QFrame(this); setMainWidget(page); QHBoxLayout *hlay = new QHBoxLayout( page); hlay->setMargin(0); QVBoxLayout *mainLayout = new QVBoxLayout(); d->m_actions=new KActionCollection(this); d->m_actions->addAssociatedWidget(this); d->m_placesView = new KFilePlacesView( page ); d->m_placesView->setModel(new KFilePlacesModel(d->m_placesView)); d->m_placesView->setObjectName( QLatin1String( "speedbar" ) ); d->m_placesView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); d->m_placesView->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); connect( d->m_placesView, SIGNAL(urlChanged(KUrl)), SLOT(setCurrentUrl(KUrl)) ); hlay->addWidget( d->m_placesView ); hlay->addLayout( mainLayout ); d->m_treeView = new KFileTreeView(page); d->m_treeView->setDirOnlyMode(true); d->m_treeView->setContextMenuPolicy(Qt::CustomContextMenu); for (int i = 1; i < d->m_treeView->model()->columnCount(); ++i) d->m_treeView->hideColumn(i); d->m_urlCombo = new KHistoryComboBox( page); d->m_urlCombo->setLayoutDirection( Qt::LeftToRight ); d->m_urlCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength); d->m_urlCombo->setTrapReturnKey( true ); KUrlCompletion *comp = new KUrlCompletion(); comp->setMode( KUrlCompletion::DirCompletion ); d->m_urlCombo->setCompletionObject( comp, true ); d->m_urlCombo->setAutoDeleteCompletionObject( true ); d->m_urlCombo->setDuplicatesEnabled( false ); d->m_contextMenu = new KMenu( this ); KAction* newFolder = new KAction( i18nc("@action:inmenu","New Folder..."), this); d->m_actions->addAction( newFolder->objectName(), newFolder ); newFolder->setIcon( KIcon( "folder-new" ) ); newFolder->setShortcut( Qt::Key_F10); connect( newFolder, SIGNAL(triggered(bool)), this, SLOT(slotNewFolder()) ); d->m_contextMenu->addAction( newFolder ); d->moveToTrash = new KAction( i18nc( "@action:inmenu","Move to Trash" ), this ); d->m_actions->addAction( d->moveToTrash->objectName(), d->moveToTrash ); d->moveToTrash->setIcon( KIcon( "user-trash" ) ); d->moveToTrash->setShortcut(KShortcut(Qt::Key_Delete)); connect( d->moveToTrash, SIGNAL(triggered(bool)), this, SLOT(slotMoveToTrash()) ); d->m_contextMenu->addAction( d->moveToTrash ); d->deleteAction = new KAction( i18nc("@action:inmenu","Delete"), this ); d->m_actions->addAction( d->deleteAction->objectName(), d->deleteAction ); d->deleteAction->setIcon( KIcon( "edit-delete" ) ); d->deleteAction->setShortcut( KShortcut( Qt::SHIFT + Qt::Key_Delete ) ); connect( d->deleteAction, SIGNAL(triggered(bool)), this, SLOT(slotDelete()) ); d->m_contextMenu->addAction( d->deleteAction ); d->m_contextMenu->addSeparator(); d->showHiddenFoldersAction = new KToggleAction( i18nc("@option:check", "Show Hidden Folders"), this ); d->m_actions->addAction( d->showHiddenFoldersAction->objectName(), d->showHiddenFoldersAction ); d->showHiddenFoldersAction->setShortcut( Qt::Key_F8 ); connect( d->showHiddenFoldersAction, SIGNAL(triggered(bool)), d->m_treeView, SLOT(setShowHiddenFiles(bool)) ); d->m_contextMenu->addAction( d->showHiddenFoldersAction ); d->m_contextMenu->addSeparator(); KAction* propertiesAction = new KAction( i18nc("@action:inmenu","Properties"), this); d->m_actions->addAction(propertiesAction->objectName(), propertiesAction); propertiesAction->setIcon(KIcon("document-properties")); propertiesAction->setShortcut(KShortcut(Qt::ALT + Qt::Key_Return)); connect( propertiesAction, SIGNAL(triggered(bool)), this, SLOT(slotProperties()) ); d->m_contextMenu->addAction( propertiesAction ); d->m_startURL = KFileDialog::getStartUrl( startDir, d->m_recentDirClass ); if ( localOnly && !d->m_startURL.isLocalFile() ) { d->m_startURL = KUrl(); QString docPath = KGlobalSettings::documentPath(); if (QDir(docPath).exists()) d->m_startURL.setPath( docPath ); else d->m_startURL.setPath( QDir::homePath() ); } d->m_startDir = d->m_startURL; d->m_rootUrl = d->m_treeView->rootUrl(); d->readConfig( KGlobal::config(), "DirSelect Dialog" ); mainLayout->addWidget( d->m_treeView, 1 ); mainLayout->addWidget( d->m_urlCombo, 0 ); connect( d->m_treeView, SIGNAL(currentChanged(KUrl)), SLOT(slotCurrentChanged())); connect( d->m_treeView, SIGNAL(activated(QModelIndex)), SLOT(slotExpand(QModelIndex))); connect( d->m_treeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(slotContextMenuRequested(QPoint))); connect( d->m_urlCombo, SIGNAL(editTextChanged(QString)), SLOT(slotComboTextChanged(QString))); connect( d->m_urlCombo, SIGNAL(activated(QString)), SLOT(slotUrlActivated(QString))); connect( d->m_urlCombo, SIGNAL(returnPressed(QString)), SLOT(slotUrlActivated(QString))); connect(this, SIGNAL(user1Clicked()), this, SLOT(slotNewFolder())); setCurrentUrl(d->m_startURL); }