void HTMLExporter::exportBasket(Basket *basket, bool isSubBasket) { if (!basket->isLoaded()) { basket->load(); } // Compute the absolute & relative paths for this basket: filesFolderPath = i18nc("HTML export folder (files)", "%1_files", filePath) + "/"; if (isSubBasket) { basketFilePath = basketsFolderPath + basket->folderName().left(basket->folderName().length() - 1) + ".html"; filesFolderName = "../"; dataFolderName = basket->folderName().left(basket->folderName().length() - 1) + "-" + i18nc("HTML export folder (data)", "data") + "/"; dataFolderPath = basketsFolderPath + dataFolderName; basketsFolderName = ""; } else { basketFilePath = filePath; filesFolderName = i18nc("HTML export folder (files)", "%1_files", KUrl(filePath).fileName()) + "/"; dataFolderName = filesFolderName + i18nc("HTML export folder (data)", "data") + "/"; dataFolderPath = filesFolderPath + i18nc("HTML export folder (data)", "data") + "/"; basketsFolderName = filesFolderName + i18nc("HTML export folder (baskets)", "baskets") + "/"; } iconsFolderName = (isSubBasket ? "../" : filesFolderName) + i18nc("HTML export folder (icons)", "icons") + "/"; // eg.: "foo.html_files/icons/" or "../icons/" imagesFolderName = (isSubBasket ? "../" : filesFolderName) + i18nc("HTML export folder (images)", "images") + "/"; // eg.: "foo.html_files/images/" or "../images/" kDebug() << "Exporting ================================================"; kDebug() << " filePath:" << filePath; kDebug() << " basketFilePath:" << basketFilePath; kDebug() << " filesFolderPath:" << filesFolderPath; kDebug() << " filesFolderName:" << filesFolderName; kDebug() << " iconsFolderPath:" << iconsFolderPath; kDebug() << " iconsFolderName:" << iconsFolderName; kDebug() << " imagesFolderPath:" << imagesFolderPath; kDebug() << " imagesFolderName:" << imagesFolderName; kDebug() << " dataFolderPath:" << dataFolderPath; kDebug() << " dataFolderName:" << dataFolderName; kDebug() << " basketsFolderPath:" << basketsFolderPath; kDebug() << " basketsFolderName:" << basketsFolderName; // Create the data folder for this basket: QDir dir; dir.mkdir(dataFolderPath); backgroundColorName = basket->backgroundColor().name().toLower().mid(1); // Generate basket icons: QString basketIcon16 = iconsFolderName + copyIcon(basket->icon(), 16); QString basketIcon32 = iconsFolderName + copyIcon(basket->icon(), 32); // Generate the [+] image for groups: QPixmap expandGroup(Note::EXPANDER_WIDTH, Note::EXPANDER_HEIGHT); expandGroup.fill(basket->backgroundColor()); QPainter painter(&expandGroup); Note::drawExpander(&painter, 0, 0, basket->backgroundColor(), /*expand=*/true, basket); painter.end(); expandGroup.save(imagesFolderPath + "expand_group_" + backgroundColorName + ".png", "PNG"); // Generate the [-] image for groups: QPixmap foldGroup(Note::EXPANDER_WIDTH, Note::EXPANDER_HEIGHT); foldGroup.fill(basket->backgroundColor()); painter.begin(&foldGroup); Note::drawExpander(&painter, 0, 0, basket->backgroundColor(), /*expand=*/false, basket); painter.end(); foldGroup.save(imagesFolderPath + "fold_group_" + backgroundColorName + ".png", "PNG"); // Open the file to write: QFile file(basketFilePath); if (!file.open(QIODevice::WriteOnly)) return; stream.setDevice(&file); stream.setCodec("UTF-8"); // Compute the colors to draw dragient for notes: QColor topBgColor; QColor bottomBgColor; Note::getGradientColors(basket->backgroundColor(), &topBgColor, &bottomBgColor); // Compute the gradient image for notes: QString gradientImageFileName = Basket::saveGradientBackground(basket->backgroundColor(), basket->Q3ScrollView::font(), imagesFolderPath); // Output the header: QString borderColor = Tools::mixColor(basket->backgroundColor(), basket->textColor()).name(); stream << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n" "<html>\n" " <head>\n" " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n" " <meta name=\"Generator\" content=\"" << KGlobal::mainComponent().aboutData()->programName() << " " << VERSION << " http://basket.kde.org/\">\n" " <style type=\"text/css\">\n" // " @media print {\n" // " span.printable { display: inline; }\n" // " }\n" " body { margin: 10px; font: 11px sans-serif; }\n" // TODO: Use user font " h1 { text-align: center; }\n" " img { border: none; vertical-align: middle; }\n"; if (withBasketTree) { stream << " .tree { margin: 0; padding: 1px 0 1px 1px; width: 150px; _width: 149px; overflow: hidden; float: left; }\n" " .tree ul { margin: 0 0 0 10px; padding: 0; }\n" " .tree li { padding: 0; margin: 0; list-style: none; }\n" " .tree a { display: block; padding: 1px; height: 16px; text-decoration: none;\n" " white-space: nowrap; word-wrap: normal; text-wrap: suppress; color: black; }\n" " .tree span { -moz-border-radius: 6px; display: block; float: left;\n" " line-height: 16px; height: 16px; vertical-align: middle; padding: 0 1px; }\n" " .tree img { vertical-align: top; padding-right: 1px; }\n" " .tree .current { background-color: " << kapp->palette().color(QPalette::Highlight).name() << "; " "-moz-border-radius: 3px 0 0 3px; border-radius: 3px 0 0 3px; color: " << kapp->palette().color(QPalette::Highlight).name() << "; }\n" " .basketSurrounder { margin-left: 152px; _margin: 0; _float: right; }\n"; } stream << " .basket { background-color: " << basket->backgroundColor().name() << "; border: solid " << borderColor << " 1px; " "font: " << Tools::cssFontDefinition(basket->Q3ScrollView::font()) << "; color: " << basket->textColor().name() << "; padding: 1px; width: 100%; }\n" " table.basket { border-collapse: collapse; }\n" " .basket * { padding: 0; margin: 0; }\n" " .basket table { width: 100%; border-spacing: 0; _border-collapse: collapse; }\n" " .column { vertical-align: top; }\n" " .columnHandle { width: " << Note::RESIZER_WIDTH << "px; background: transparent url('" << imagesFolderName << "column_handle_" << backgroundColorName << ".png') repeat-y; }\n" " .group { margin: 0; padding: 0; border-collapse: collapse; width: 100% }\n" " .groupHandle { margin: 0; width: " << Note::GROUP_WIDTH << "px; text-align: center; }\n" " .note { padding: 1px 2px; background: " << bottomBgColor.name() << " url('" << imagesFolderName << gradientImageFileName << "')" " repeat-x; border-top: solid " << topBgColor.name() << " 1px; border-bottom: solid " << Tools::mixColor(topBgColor, bottomBgColor).name() << " 1px; width: 100%; }\n" " .tags { width: 1px; white-space: nowrap; }\n" " .tags img { padding-right: 2px; }\n" << LinkLook::soundLook->toCSS("sound", basket->textColor()) << LinkLook::fileLook->toCSS("file", basket->textColor()) << LinkLook::localLinkLook->toCSS("local", basket->textColor()) << LinkLook::networkLinkLook->toCSS("network", basket->textColor()) << LinkLook::launcherLook->toCSS("launcher", basket->textColor()) << " .unknown { margin: 1px 2px; border: 1px solid " << borderColor << "; -moz-border-radius: 4px; }\n"; QList<State*> states = basket->usedStates(); QString statesCss; for (State::List::Iterator it = states.begin(); it != states.end(); ++it) statesCss += (*it)->toCSS(imagesFolderPath, imagesFolderName, basket->Q3ScrollView::font()); stream << statesCss << " .credits { text-align: right; margin: 3px 0 0 0; _margin-top: -17px; font-size: 80%; color: " << borderColor << "; }\n" " </style>\n" " <title>" << Tools::textToHTMLWithoutP(basket->basketName()) << "</title>\n" " <link rel=\"shortcut icon\" type=\"image/png\" href=\"" << basketIcon16 << "\">\n"; // Create the column handle image: QPixmap columnHandle(Note::RESIZER_WIDTH, 50); painter.begin(&columnHandle); Note::drawInactiveResizer(&painter, 0, 0, columnHandle.height(), basket->backgroundColor(), /*column=*/true); painter.end(); columnHandle.save(imagesFolderPath + "column_handle_" + backgroundColorName + ".png", "PNG"); stream << " </head>\n" " <body>\n" " <h1><img src=\"" << basketIcon32 << "\" width=\"32\" height=\"32\" alt=\"\"> " << Tools::textToHTMLWithoutP(basket->basketName()) << "</h1>\n"; if (withBasketTree) writeBasketTree(basket); // If filtering, only export filtered notes, inform to the user: // TODO: Filtering tags too!! // TODO: Make sure only filtered notes are exported! // if (decoration()->filterData().isFiltering) // stream << // " <p>" << i18n("Notes matching the filter "%1":").arg(Tools::textToHTMLWithoutP(decoration()->filterData().string)) << "</p>\n"; stream << " <div class=\"basketSurrounder\">\n"; if (basket->isColumnsLayout()) stream << " <table class=\"basket\">\n" " <tr>\n"; else stream << " <div class=\"basket\" style=\"position: relative; height: " << basket->contentsHeight() << "px; width: " << basket->contentsWidth() << "px; min-width: 100%;\">\n"; for (Note *note = basket->firstNote(); note; note = note->next()) exportNote(note, /*indent=*/(basket->isFreeLayout() ? 4 : 5)); // Output the footer: if (basket->isColumnsLayout()) stream << " </tr>\n" " </table>\n"; else stream << " </div>\n"; stream << QString( " </div>\n" " <p class=\"credits\">%1</p>\n").arg( i18n("Made with <a href=\"http://basket.kde.org/\">%1</a> %2, a KDE tool to take notes and keep information at hand.", KGlobal::mainComponent().aboutData()->programName(), VERSION)); // Copy a transparent GIF image in the folder, needed for the JavaScript hack: QString gifFileName = "spacer.gif"; QFile transGIF(imagesFolderPath + gifFileName); if (!transGIF.exists() && transGIF.open(QIODevice::WriteOnly)) { QDataStream streamGIF(&transGIF); // This is a 1px*1px transparent GIF image: const char blankGIF[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x0a, 0x00, 0x0a, 0x00, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x21, 0xfe, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x0a, 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x08, 0x8c, 0x8f, 0xa9, 0xcb, 0xed, 0x0f, 0x63, 0x2b, 0x00, 0x3b }; streamGIF.writeRawData(blankGIF, 74); transGIF.close(); } stream << " <!--[if lt IE 7]>\n" " <script>\n" " function fixPng(img) {\n" " if (!img.style.filter) {\n" " img.style.filter = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" + img.src + \"')\";\n" " img.src = \"" << imagesFolderName << gifFileName << "\";\n" " }\n" " }\n" " for (i = document.images.length - 1; i >= 0; i -= 1) {\n" " var img = document.images[i];\n" " if (img.src.substr(img.src.length - 4) == \".png\")\n" " if (img.complete)\n" " fixPng(img);\n" " else\n" " img.attachEvent(\"onload\", function() { fixPng(window.event.srcElement); });\n" " }\n" " </script>\n" " <![endif]-->\n" " </body>\n" "</html>\n"; file.close(); stream.setDevice(0); progress->setValue(progress->value()+1); // Basket exportation finished // Recursively export child baskets: BasketListViewItem *item = Global::bnpView->listViewItemForBasket(basket); if (item->childCount() >=0) { for (int i=0; i < item->childCount(); i++) { exportBasket(((BasketListViewItem *)item->child(i))->basket(), /*isSubBasket=*/true); } } }
void HTMLExporter::exportNote(Note *note, int indent) { QString spaces; if (note->isColumn()) { QString width = ""; if (false/*TODO: DEBUG AND REENABLE: hasResizer()*/) { // As we cannot be precise in CSS (say eg. "width: 50%-40px;"), // we output a percentage that is approximatively correct. // For instance, we compute the currently used percentage of width in the basket // and try make make it the same on a 1024*768 display in a Web browser: int availableSpaceForColumnsInThisBasket = note->basket()->contentsWidth() - (note->basket()->columnsCount() - 1) * Note::RESIZER_WIDTH; int availableSpaceForColumnsInBrowser = 1024 /* typical screen width */ - 25 /* window border and scrollbar width */ - 2 * 5 /* page margin */ - (note->basket()->columnsCount() - 1) * Note::RESIZER_WIDTH; if (availableSpaceForColumnsInThisBasket <= 0) availableSpaceForColumnsInThisBasket = 1; int widthValue = (int)(availableSpaceForColumnsInBrowser * (double) note->groupWidth() / availableSpaceForColumnsInThisBasket); if (widthValue <= 0) widthValue = 1; if (widthValue > 100) widthValue = 100; width = QString(" width=\"%1%\"").arg(QString::number(widthValue)); } stream << spaces.fill(' ', indent) << "<td class=\"column\"" << width << ">\n"; // Export child notes: for (Note *child = note->firstChild(); child; child = child->next()) { stream << spaces.fill(' ', indent + 1); exportNote(child, indent + 1); stream << '\n'; } stream << spaces.fill(' ', indent) << "</td>\n"; if (note->hasResizer()) stream << spaces.fill(' ', indent) << "<td class=\"columnHandle\"></td>\n"; return; } QString freeStyle; if (note->isFree()) freeStyle = " style=\"position: absolute; left: " + QString::number(note->x()) + "px; top: " + QString::number(note->y()) + "px; width: " + QString::number(note->groupWidth()) + "px\""; if (note->isGroup()) { stream << '\n' << spaces.fill(' ', indent) << "<table" << freeStyle << ">\n"; // Note content is expected to be on the same HTML line, but NOT groups int i = 0; for (Note *child = note->firstChild(); child; child = child->next()) { stream << spaces.fill(' ', indent); if (i == 0) stream << " <tr><td class=\"groupHandle\"><img src=\"" << imagesFolderName << (note->isFolded() ? "expand_group_" : "fold_group_") << backgroundColorName << ".png" << "\" width=\"" << Note::EXPANDER_WIDTH << "\" height=\"" << Note::EXPANDER_HEIGHT << "\"></td>\n"; else if (i == 1) stream << " <tr><td class=\"freeSpace\" rowspan=\"" << note->countDirectChilds() << "\"></td>\n"; else stream << " <tr>\n"; stream << spaces.fill(' ', indent) << " <td>"; exportNote(child, indent + 3); stream << "</td>\n" << spaces.fill(' ', indent) << " </tr>\n"; ++i; } stream << '\n' << spaces.fill(' ', indent) << "</table>\n" /*<< spaces.fill(' ', indent - 1)*/; } else { // Additionnal class for the content (link, netword, color...): QString additionnalClasses = note->content()->cssClass(); if (!additionnalClasses.isEmpty()) additionnalClasses = " " + additionnalClasses; // Assign the style of each associted tags: for (State::List::Iterator it = note->states().begin(); it != note->states().end(); ++it) additionnalClasses += " tag_" + (*it)->id(); //stream << spaces.fill(' ', indent); stream << "<table class=\"note" << additionnalClasses << "\"" << freeStyle << "><tr>"; if (note->emblemsCount() > 0) { stream << "<td class=\"tags\"><nobr>"; for (State::List::Iterator it = note->states().begin(); it != note->states().end(); ++it) if (!(*it)->emblem().isEmpty()) { int emblemSize = 16; QString iconFileName = copyIcon((*it)->emblem(), emblemSize); stream << "<img src=\"" << iconsFolderName << iconFileName << "\" width=\"" << emblemSize << "\" height=\"" << emblemSize << "\" alt=\"" << (*it)->textEquivalent() << "\" title=\"" << (*it)->fullName() << "\">"; } stream << "</nobr></td>"; } stream << "<td>"; note->content()->exportToHTML(this, indent); stream << "</td></tr></table>"; } }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { EdamProtocol *edam = EdamProtocol::GetInstance(); ui->setupUi(this); pdfCache * pdf = new pdfCache(this); CustomNetworkAccessManager *nm = new CustomNetworkAccessManager(ui->editor->page()->networkAccessManager(), this, pdf); edam->setCNAM(nm); ui->editor->page()->setNetworkAccessManager(nm); Speller::setSettings(new DBSpellSettings(this, ui->editor)); ui->editor->setContextMenuPolicy(Qt::CustomContextMenu); ui->editor->load(QUrl("qrc:///html/noteajax.html")); jsB = new jsBridge(this, pdf); jsB->setWebView(ui->editor); enmlWritter = new enml2(this); connect(ui->editor->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJSObject())); loaded = false; editingEnabled = false; tagsActions = new QActionGroup(this); newTag = new TagLabel(this); newTag->hide(); ui->tagsBar->addWidget(newTag); appIcon = QIcon(":img/hippo64.png"); trayIcon = NULL; bool sysTrayEnabled = sql::readSyncStatus("systemTray", true).toBool(); if (QSystemTrayIcon::isSystemTrayAvailable() && sysTrayEnabled) enableSystemTrayIcon(true); connect(edam, SIGNAL(AuthenticateFailed()), this, SLOT(authentificationFailed())); connect(edam, SIGNAL(syncFinished()), this, SLOT(syncFinished())); connect(edam, SIGNAL(syncStarted(int)), this, SLOT(syncStarted(int))); connect(edam, SIGNAL(noteGuidChanged(QString,QString)), this, SLOT(changeNoteGuid(QString,QString))); connect(ui->notebooks, SIGNAL(itemSelectionChanged()), this, SLOT(switchNotebook())); connect(ui->tags, SIGNAL(itemSelectionChanged()), this, SLOT(switchTag())); connect(ui->tags, SIGNAL(tagAdded(QString,QString)), this, SLOT(addTag(QString,QString))); connect(ui->tags, SIGNAL(tagsUpdated()), this, SLOT(updateTagsToolBar())); connect(ui->tags, SIGNAL(tagsUpdated()), this, SLOT(switchTag())); connect(ui->NotesList, SIGNAL(noteSwitched()), this, SLOT(switchNote())); connect(ui->action_Abaut, SIGNAL(triggered()), this, SLOT(loadAboutInfo())); connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(closeWindow())); connect(ui->actionNew_Note, SIGNAL(triggered()), this, SLOT(newNote())); connect(ui->actionSync, SIGNAL(triggered()), this, SLOT(sync())); connect(ui->noteTitle, SIGNAL(textEdited(QString)), this, SLOT(noteTitleChange(QString))); connect(ui->actionAccount_info, SIGNAL(triggered()), this, SLOT(showUserInfo())); connect(ui->editor->page(), SIGNAL(linkClicked(QUrl)), this, SLOT(openURL(QUrl))); connect(ui->editor->page(), SIGNAL(microFocusChanged()), this, SLOT(updateEditButtonsState())); connect(ui->editor, SIGNAL(selectionChanged()), this, SLOT(updateSelectionButtonsState())); connect(ui->editor->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest))); connect(ui->editor, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(editorContextMenuRequested(QPoint))); connect(ui->editor, SIGNAL(fileInserted(QString)), this, SLOT(insertFile(QString))); connect(ui->notebooks, SIGNAL(noteMoved(QString,QString)), this, SLOT(moveNote(QString,QString))); connect(ui->notebooks, SIGNAL(noteDeleted(QString)), this, SLOT(deleteNote(QString))); connect(ui->notebooks, SIGNAL(noteRestored(QString,QString)), this, SLOT(restoreNote(QString,QString))); connect(ui->NotesList, SIGNAL(noteDeleted(QString)), this, SLOT(deleteNote(QString))); connect(ui->NotesList, SIGNAL(noteRestored(QString)), this, SLOT(restoreNote(QString))); connect(ui->NotesList, SIGNAL(noteCreated()), this, SLOT(newNote())); connect(ui->NotesList, SIGNAL(reloaded()), this, SLOT(updateCurrentNoteName())); connect(ui->editButton, SIGNAL(toggled(bool)), this, SLOT(setEditable(bool))); connect(ui->actionDelete_Note, SIGNAL(triggered()), this, SLOT(deleteNote())); connect(ui->toolBox, SIGNAL(currentChanged(int)), this, SLOT(changeTab(int))); connect(ui->editor->page(), SIGNAL(linkHovered(QString,QString,QString)), this, SLOT(linkHovered(QString,QString,QString))); connect(jsB, SIGNAL(hintMessage(QString,int)), ui->statusbar, SLOT(showMessage(QString,int))); connect(jsB, SIGNAL(noteChanged(QString)), this, SLOT(updateTagsToolBar(QString))); connect(jsB, SIGNAL(activeNoteSelectionChanged(bool)), ui->actionDelete_Note, SLOT(setEnabled(bool))); connect(jsB, SIGNAL(activeNoteSelectionChanged(bool)), ui->editButton, SLOT(setEnabled(bool))); connect(jsB, SIGNAL(editingStarted(bool)), ui->editButton, SLOT(setChecked(bool))); connect(jsB, SIGNAL(titleUpdated(QString,QString)), this, SLOT(updateNoteTitle(QString,QString))); connect(jsB, SIGNAL(conflictAdded(qint64,QString,bool)), this, SLOT(addConflict(qint64,QString,bool))); connect(jsB, SIGNAL(noteSelectionChanged(bool)), ui->actionNote_Info, SLOT(setEnabled(bool))); connect(jsB, SIGNAL(noteSelectionChanged(bool)), ui->actionExport, SLOT(setEnabled(bool))); connect(jsB, SIGNAL(noteSelectionChanged(bool)), ui->actionPrint, SLOT(setEnabled(bool))); connect(ui->editor, SIGNAL(tagUpdated(QString,bool)), this, SLOT(updateTag(QString,bool))); connect(tagsActions, SIGNAL(triggered(QAction*)), this, SLOT(tagClicked(QAction*))); connect(newTag, SIGNAL(tagCreated(QString)), this, SLOT(createTag(QString))); connect(ui->actionKeep_only_this_Version, SIGNAL(triggered()), this, SLOT(keepThisVersion())); connect(ui->actionNote_Info, SIGNAL(triggered()), this, SLOT(showNoteInfo())); connect(ui->actionExport, SIGNAL(triggered()), this, SLOT(exportNote())); connect(ui->actionPrint, SIGNAL(triggered()), this, SLOT(print())); connect(this, SIGNAL(titleChanged(QString,QString)), jsB, SIGNAL(titleChanged(QString,QString))); setWindowIcon(appIcon); setWindowTitle("Hippo Notes"); setTabOrder(ui->noteTitle, ui->editor); ui->notebooks->setSortingEnabled(true); ui->notebooks->sortByColumn(0, Qt::AscendingOrder); ui->editBar->setVisible(false); ui->mainToolBar->addAction(ui->actionNew_Note); ui->mainToolBar->addAction(ui->actionSync); QFontComboBox *font = new QFontComboBox(this); font->setDisabled(true); font->setFontFilters(QFontComboBox::ScalableFonts); font->setEditable(false); connect(this, SIGNAL(editButtonsStateChanged(bool)), font, SLOT(setEnabled(bool))); connect(this, SIGNAL(updateFont(QFont)), font, SLOT(setCurrentFont(QFont))); connect(font, SIGNAL(activated(QString)), this, SLOT(changeFont(QString))); ui->editBar->addWidget(font); QComboBox *fontSize = new QComboBox(this); fontSize->setDisabled(true); fontSize->setEditable(false); for (int i = 1; i <= 7; i++) fontSize->addItem(QString::number(i)); connect(this, SIGNAL(editButtonsStateChanged(bool)), fontSize, SLOT(setEnabled(bool))); connect(this, SIGNAL(updateFontSize(int)), fontSize, SLOT(setCurrentIndex(int))); connect(fontSize, SIGNAL(activated(QString)), this, SLOT(changeFontSize(QString))); ui->editBar->addWidget(fontSize); QAction *boldIco = ui->editor->pageAction(QWebPage::ToggleBold); boldIco->setIcon(QIcon::fromTheme("format-text-bold")); ui->editBar->addAction(boldIco); QAction *italicIco = ui->editor->pageAction(QWebPage::ToggleItalic); italicIco->setIcon(QIcon::fromTheme("format-text-italic")); ui->editBar->addAction(italicIco); QAction *underlineIco = ui->editor->pageAction(QWebPage::ToggleUnderline); underlineIco->setIcon(QIcon::fromTheme("format-text-underline")); ui->editBar->addAction(underlineIco); QAction *strikethroughIco = ui->editor->pageAction(QWebPage::ToggleStrikethrough); strikethroughIco->setIcon(QIcon::fromTheme("format-text-strikethrough")); ui->editBar->addAction(strikethroughIco); ui->editBar->addSeparator(); QAction *undoIco = ui->editor->pageAction(QWebPage::Undo); undoIco->setIcon(QIcon::fromTheme("edit-undo")); undoIco->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z)); ui->editBar->addAction(undoIco); ui->menu_Edit->addAction(undoIco); QAction *redoIco = ui->editor->pageAction(QWebPage::Redo); redoIco->setIcon(QIcon::fromTheme("edit-redo")); redoIco->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z)); ui->editBar->addAction(redoIco); ui->menu_Edit->addAction(redoIco); ui->editBar->addSeparator(); QAction *rformatIco = ui->editor->pageAction(QWebPage::RemoveFormat); rformatIco->setIcon(QIcon::fromTheme("edit-clear")); ui->editBar->addAction(rformatIco); ui->editBar->addSeparator(); QAction *leftIco = ui->editor->pageAction(QWebPage::AlignLeft); leftIco->setIcon(QIcon::fromTheme("format-justify-left")); ui->editBar->addAction(leftIco); QAction *centerIco = ui->editor->pageAction(QWebPage::AlignCenter); centerIco->setIcon(QIcon::fromTheme("format-justify-center")); ui->editBar->addAction(centerIco); QAction *rightIco = ui->editor->pageAction(QWebPage::AlignRight); rightIco->setIcon(QIcon::fromTheme("format-justify-right")); ui->editBar->addAction(rightIco); QAction *fillIco = ui->editor->pageAction(QWebPage::AlignJustified); fillIco->setIcon(QIcon::fromTheme("format-justify-fill")); ui->editBar->addAction(fillIco); ui->editBar->addSeparator(); QAction *indentIco = ui->editor->pageAction(QWebPage::Indent); indentIco->setIcon(QIcon::fromTheme("format-indent-more")); ui->editBar->addAction(indentIco); QAction *outdentIco = ui->editor->pageAction(QWebPage::Outdent); outdentIco->setIcon(QIcon::fromTheme("format-indent-less")); ui->editBar->addAction(outdentIco); QAction *superscriptIco = ui->editor->pageAction(QWebPage::ToggleSuperscript); superscriptIco->setIcon(QIcon::fromTheme("format-text-superscript")); ui->editBar->addAction(superscriptIco); QAction *subscriptIco = ui->editor->pageAction(QWebPage::ToggleSubscript); subscriptIco->setIcon(QIcon::fromTheme("format-text-subscript")); ui->editBar->addAction(subscriptIco); QAction *unorderedIco = ui->editor->pageAction(QWebPage::InsertUnorderedList); unorderedIco->setIcon(QIcon::fromTheme("format-list-unordered")); ui->editBar->addAction(unorderedIco); QAction *orderedIco = ui->editor->pageAction(QWebPage::InsertOrderedList); orderedIco->setIcon(QIcon::fromTheme("format-list-ordered")); ui->editBar->addAction(orderedIco); QAction *lineIco = new QAction("Insert horizontal line", this); lineIco->setIcon(QIcon::fromTheme("insert-horizontal-rule")); lineIco->setDisabled(true); connect(this, SIGNAL(editButtonsStateChanged(bool)), lineIco, SLOT(setEnabled(bool))); connect(lineIco, SIGNAL(triggered()), this, SLOT(insertHorizontalLine())); ui->editBar->addAction(lineIco); ui->menu_Edit->addSeparator(); QAction *cutIco = ui->editor->pageAction(QWebPage::Cut); cutIco->setIcon(QIcon::fromTheme("edit-cut")); cutIco->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X)); ui->menu_Edit->addAction(cutIco); QAction *copyIco = ui->editor->pageAction(QWebPage::Copy); copyIco->setIcon(QIcon::fromTheme("edit-copy")); copyIco->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C)); ui->menu_Edit->addAction(copyIco); QAction *pasteIco = ui->editor->pageAction(QWebPage::Paste); pasteIco->setIcon(QIcon::fromTheme("edit-paste")); pasteIco->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_V)); ui->menu_Edit->addAction(pasteIco); QAction *pasteSpecialIco = ui->editor->pageAction(QWebPage::PasteAndMatchStyle); pasteSpecialIco->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V)); ui->menu_Edit->addAction(pasteSpecialIco); ui->menu_Edit->addSeparator(); QAction *insertUrlIco = new QAction("Create link", this); insertUrlIco->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); insertUrlIco->setDisabled(true); insertUrlIco->setIcon(QIcon::fromTheme("insert-link")); connect(this, SIGNAL(selectionButtonsStateChanged(bool)), insertUrlIco, SLOT(setDisabled(bool))); connect(insertUrlIco, SIGNAL(triggered()), this, SLOT(insertUrl())); ui->menu_Edit->addAction(insertUrlIco); QAction *todoIco = new QAction("Insert To-do Checkbox", this); todoIco->setIcon(QIcon::fromTheme("checkbox")); todoIco->setDisabled(true); connect(this, SIGNAL(editButtonsStateChanged(bool)), todoIco, SLOT(setEnabled(bool))); connect(todoIco, SIGNAL(triggered()), jsB, SIGNAL(insertToDo())); ui->menu_Edit->addAction(todoIco); QAction *insertImage = new QAction("Insert Image", this); insertImage->setIcon(QIcon::fromTheme("insert-image")); insertImage->setDisabled(true); connect(this, SIGNAL(editButtonsStateChanged(bool)), insertImage, SLOT(setEnabled(bool))); connect(insertImage, SIGNAL(triggered()), this, SLOT(insertImg())); ui->menu_Edit->addAction(insertImage); QAction *insertFile = new QAction("Insert File", this); insertFile->setDisabled(true); connect(this, SIGNAL(editButtonsStateChanged(bool)), insertFile, SLOT(setEnabled(bool))); connect(insertFile, SIGNAL(triggered()), this, SLOT(insertFile())); ui->menu_Edit->addAction(insertFile); QAction *encryptIco = new QAction("Encrypt Selected Text...", this); encryptIco->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_X)); encryptIco->setDisabled(true); encryptIco->setIcon(QIcon::fromTheme("document-edit-encrypt")); connect(this, SIGNAL(selectionButtonsStateChanged(bool)), encryptIco, SLOT(setDisabled(bool))); connect(encryptIco, SIGNAL(triggered()), jsB, SIGNAL(encryptText())); ui->menu_Edit->addAction(encryptIco); ui->menu_Edit->addSeparator(); QAction *options = new QAction("&Options...", this); options->setIcon(QIcon::fromTheme("preferences-other")); connect(options, SIGNAL(triggered()), this, SLOT(showOptions())); ui->menu_Edit->addAction(options); clearConflictBar(); connect(jsB, SIGNAL(showConflict()), ui->conflictBar, SLOT(show())); connect(jsB, SIGNAL(showConflict()), ui->conflictBarBottom, SLOT(show())); conflictsGroup = new QActionGroup(this); connect(conflictsGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeNoteVersion(QAction*))); searchIndex = new SearchIndex(this); connect(ui->searchButton, SIGNAL(clicked()), this, SLOT(search())); connect(edam, SIGNAL(syncFinished()), searchIndex, SLOT(buildSearchIndex())); connect(jsB, SIGNAL(noteUpdated(QString)), searchIndex, SLOT(updateNoteIndex(QString))); connect(edam, SIGNAL(noteUpdated(QString)), searchIndex, SLOT(dropNoteIndex(QString))); connect(ui->searchInput, SIGNAL(returnPressed()), this, SLOT(search())); QByteArray mainWindowGeometry = sql::readSyncStatus("mainWindowGeometry").toString().toLatin1(); if (!mainWindowGeometry.isEmpty()) restoreGeometry(QByteArray::fromBase64(mainWindowGeometry)); QByteArray mainWidgetsSplitterState = sql::readSyncStatus("mainWidgetsSplitterState").toString().toLatin1(); if (!mainWidgetsSplitterState.isEmpty()) ui->mainWidgetsSplitter->restoreState(QByteArray::fromBase64(mainWidgetsSplitterState)); //showWindow(); edam->init(); }