#include #include "mainwindowimpl.h" #include "searchboximpl.h" #include "styleeditorimpl.h" #include "configurationdlgimpl.h" #include "aboutdialogimpl.h" #include "propertydlgimpl.h" /* MainWindow construtor. */ MainWindowImpl::MainWindowImpl( QWidget * parent, Qt::WFlags f) : QMainWindow(parent, f) { // Setup UI setupUi(this); createTreeDock(); // Search will be implemented later. //createSearchDock(); createFontWidgets(); createContextMenu(); createSysTray(); FinalizeUI(); mainModel = NULL; m_closeFromMenu = false; // Load and apply configuration m_confManager = new ConfigurationManager(this->AppName()); applyConfiguration(); // Load styles m_styleManager = new StyleManager(); m_styleManager->updateComboStyle(comboStyle); // Read window, toolbars and docks size/position. readSettings(); // Open last file if requested, else open an empty new file. if (m_confManager->openLastFile) openFile(m_confManager->lastFile); else { on_action_New_triggered(); } } /* Some kind of "constants". Maybe to be done another way. */ QString MainWindowImpl::AppDisplayName() { return "Nagaina"; } QString MainWindowImpl::AppName() { return "nagaina"; } QString MainWindowImpl::AppVersion() { return "0.1.2"; } QString MainWindowImpl::AppEditor() { return "JD"; } /* UI complementary implementation. */ /* Misc. UI stuff. */ void MainWindowImpl::FinalizeUI() { // Main window title this->setWindowTitle(AppDisplayName() + " - " + AppVersion()); // Add toolbar to menu menu_Toolbars->addAction(fileToolBar->toggleViewAction()); menu_Toolbars->addAction(editToolBar->toggleViewAction()); menu_Toolbars->addAction(formatToolBar->toggleViewAction()); menu_Toolbars->addAction(styleToolBar->toggleViewAction()); menu_Toolbars->addAction(fontToolBar->toggleViewAction()); // Initialize "paste" action. connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(onClipboardDataChanged())); actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty()); onFontChanged(textEdit->font()); onColorChanged(textEdit->textColor()); onAlignmentChanged(textEdit->alignment()); } /* Create police and size combo boxes, and alignement actions. */ void MainWindowImpl::createFontWidgets() { // Style tool bar styleToolBar = new QToolBar(this); styleToolBar->setObjectName("styleToolBar"); styleToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea | Qt::LeftToolBarArea | Qt::RightToolBarArea); styleToolBar->setWindowTitle(tr("Styles")); addToolBarBreak(Qt::TopToolBarArea); addToolBar(styleToolBar); comboStyle = new QComboBox(styleToolBar); comboStyle->setObjectName("comboStyle"); comboStyle->setEditable(false); comboStyle->setSizeAdjustPolicy(QComboBox::AdjustToContents); styleToolBar->addWidget(comboStyle); connect(action_Apply_current_style, SIGNAL(triggered()), this, SLOT(on_action_Apply_current_style_triggered())); styleToolBar->addAction(action_Apply_current_style); // Create Toolbar for size and police combos. fontToolBar = new QToolBar(this); fontToolBar->setObjectName("fontToolBar"); fontToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea | Qt::LeftToolBarArea | Qt::RightToolBarArea); fontToolBar->setWindowTitle(tr("Font")); addToolBar(fontToolBar); // Police combo. comboFont = new QFontComboBox(fontToolBar); fontToolBar->addWidget(comboFont); connect(comboFont, SIGNAL(activated(const QString &)), this, SLOT(onTextFamily(const QString &))); comboFont->setEditable(false); // Size combo. comboSize = new QComboBox(fontToolBar); comboSize->setObjectName("comboSize"); fontToolBar->addWidget(comboSize); comboSize->setEditable(false); // Fill size combo. QFontDatabase db; foreach(int size, db.standardSizes()) comboSize->addItem(QString::number(size)); connect(comboSize, SIGNAL(activated(const QString &)), this, SLOT(onTextSize(const QString &))); comboSize->setCurrentIndex(comboSize->findText(QString::number(QApplication::font().pointSize()))); // Color action : draw with current color. QPixmap pix(16, 16); pix.fill(Qt::black); action_Color->setIcon(pix); // Alignment actions. QActionGroup *grp = new QActionGroup(this); connect(grp, SIGNAL(triggered(QAction *)), this, SLOT(onTextAlign(QAction *))); actionAlignLeft = new QAction(QIcon(":/textleft.png"), tr("&Left"), grp); actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); actionAlignLeft->setCheckable(true); actionAlignCenter = new QAction(QIcon(":/textcenter.png"), tr("C&enter"), grp); actionAlignCenter->setShortcut(Qt::CTRL + Qt::Key_E); actionAlignCenter->setCheckable(true); actionAlignRight = new QAction(QIcon(":/textright.png"), tr("&Right"), grp); actionAlignRight->setShortcut(Qt::CTRL + Qt::Key_R); actionAlignRight->setCheckable(true); actionAlignJustify = new QAction(QIcon(":/textjustify.png"), tr("&Justify"), grp); actionAlignJustify->setShortcut(Qt::CTRL + Qt::Key_J); actionAlignJustify->setCheckable(true); formatToolBar->addActions(grp->actions()); menuAlignment->addActions(grp->actions()); } /* Create Systray object */ void MainWindowImpl::createSysTray() { /* actionSysShow = new QAction(tr("Show"), this); connect(actionSysShow, SIGNAL(triggered( )), this, SLOT(onActionSysShow( ))); actionSysClose = new QAction(QIcon(":/exit.png"), tr("Quit"), this); connect(actionSysClose, SIGNAL(triggered( )), this, SLOT(onActionSysClose( ))); sysTrayMenu = new QMenu(this); sysTrayMenu->addAction(actionSysShow); sysTrayMenu->addSeparator(); sysTrayMenu->addAction(actionSysClose); m_trayIcon->setContextMenu(sysTrayMenu); */ m_trayIcon = new QSystemTrayIcon(QIcon(":/nagaina.png"), this); m_trayIcon->setToolTip(AppDisplayName()); connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason )), this, SLOT(onTrayIconActivated(QSystemTrayIcon::ActivationReason ))); } /* Create Tree Widget context menu. */ void MainWindowImpl::createContextMenu() { actionAddRootCategory = new QAction(QIcon(":/addrootcategory.png"), tr("Add root category..."), this); connect(actionAddRootCategory, SIGNAL(triggered( )), this, SLOT(onActionAddRootCategory( ))); actionAddRootPage = new QAction(QIcon(":/addrootpage.png"), tr("Add root page..."), this); connect(actionAddRootPage, SIGNAL(triggered( )), this, SLOT(onActionAddRootPage( ))); actionMenuAddCategory = new QAction(QIcon(":/addcategory.png"), tr("Add category..."), this); connect(actionMenuAddCategory, SIGNAL(triggered( )), this, SLOT(onActionMenuAddCategory( ))); actionMenuAddPage = new QAction(QIcon(":/addpage.png"), tr("Add page..."), this); connect(actionMenuAddPage, SIGNAL(triggered( )), this, SLOT(onActionMenuAddPage( ))); actionMenuRename = new QAction(tr("Rename..."), this); connect(actionMenuRename, SIGNAL(triggered( )), this, SLOT(onActionMenuRename( ))); actionMenuDelete = new QAction(QIcon(":/delete.png"), tr("Delete..."), this); connect(actionMenuDelete, SIGNAL(triggered( )), this, SLOT(onActionMenuDelete( ))); actionMenuMoveLeft = new QAction(QIcon(":/leftarrow.png"), tr("Move left"), this); actionMenuMoveLeft->setShortcut(Qt::ALT + Qt::Key_Left); connect(actionMenuMoveLeft, SIGNAL(triggered( )), this, SLOT(onActionMenuMoveLeft( ))); actionMenuMoveRight = new QAction(QIcon(":/rightarrow.png"), tr("Move right"), this); actionMenuMoveRight->setShortcut(Qt::ALT + Qt::Key_Right); connect(actionMenuMoveRight, SIGNAL(triggered( )), this, SLOT(onActionMenuMoveRight( ))); actionMenuMoveUp = new QAction(QIcon(":/uparrow.png"), tr("Move up"), this); actionMenuMoveUp->setShortcut(Qt::ALT + Qt::Key_Up); connect(actionMenuMoveUp, SIGNAL(triggered( )), this, SLOT(onActionMenuMoveUp( ))); actionMenuMoveDown = new QAction(QIcon(":/downarrow.png"), tr("Move down"), this); actionMenuMoveDown->setShortcut(Qt::ALT + Qt::Key_Down); connect(actionMenuMoveDown, SIGNAL(triggered( )), this, SLOT(onActionMenuMoveDown( ))); actionMenuProperty = new QAction(tr("Property..."), this); connect(actionMenuProperty, SIGNAL(triggered( )), this, SLOT(onActionMenuProperty( ))); actionMenuAddCategory->setEnabled(false); actionMenuAddPage->setEnabled(false); actionMenuRename->setEnabled(false); actionMenuDelete->setEnabled(false); actionMenuMoveUp->setEnabled(false); actionMenuMoveDown->setEnabled(false); actionMenuMoveLeft->setEnabled(false); actionMenuMoveRight->setEnabled(false); actionMenuProperty->setEnabled(false); // Add actions to context menu. contextMenu = new QMenu(this); contextMenu->addAction(actionMenuAddCategory); contextMenu->addAction(actionMenuAddPage); contextMenu->addSeparator(); contextMenu->addAction(actionMenuMoveUp); contextMenu->addAction(actionMenuMoveDown); contextMenu->addAction(actionMenuMoveLeft); contextMenu->addAction(actionMenuMoveRight); contextMenu->addSeparator(); contextMenu->addAction(actionMenuRename); contextMenu->addAction(actionMenuDelete); contextMenu->addSeparator(); contextMenu->addAction(actionMenuProperty); // Add actions to tree view tool bar treeToolBar->addAction(actionAddRootCategory); treeToolBar->addAction(actionAddRootPage); treeToolBar->addAction(actionMenuMoveUp); treeToolBar->addAction(actionMenuMoveDown); treeToolBar->addAction(actionMenuMoveLeft); treeToolBar->addAction(actionMenuMoveRight); // Add actions to main menu. menuItems->addAction(actionAddRootCategory); menuItems->addAction(actionAddRootPage); menuItems->addSeparator(); menuItems->addAction(actionMenuAddCategory); menuItems->addAction(actionMenuAddPage); menuItems->addSeparator(); menuItems->addAction(actionMenuMoveUp); menuItems->addAction(actionMenuMoveDown); menuItems->addAction(actionMenuMoveLeft); menuItems->addAction(actionMenuMoveRight); menuItems->addSeparator(); menuItems->addAction(actionMenuRename); menuItems->addAction(actionMenuDelete); menuItems->addSeparator(); menuItems->addAction(actionMenuProperty); } /* Create file TreeView in a dock. */ void MainWindowImpl::createTreeDock() { QDockWidget *dock = new QDockWidget(tr("Explorer"), this); dock->setObjectName("dockExplorer"); dock->setAllowedAreas(Qt::AllDockWidgetAreas); QWidget *container = new QWidget; container->setContentsMargins(0, 0, 0, 0); QVBoxLayout *layout = new QVBoxLayout(); layout->setMargin(0); layout->setSpacing(0); treeWidget = new QTreeWidget(dock); treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); treeWidget->setHeaderLabel(""); connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(onTreeClick(QTreeWidgetItem *, int))); connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onTreeContextMenuRequested(QPoint))); connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(onCurrentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))); treeToolBar = new QToolBar(dock); treeToolBar->setIconSize(QSize(20, 20)); treeToolBar->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); layout->addWidget(treeToolBar); layout->addWidget(treeWidget); container->setLayout(layout); dock->setWidget(container); addDockWidget(Qt::LeftDockWidgetArea, dock); dock->toggleViewAction()->setShortcut(Qt::Key_F6); menu_Display->addAction(dock->toggleViewAction()); } /* Create advanced search dialog dock. Unused at the moment. */ void MainWindowImpl::createSearchDock() { searchBox = new SearchBoxImpl(0); searchDock = searchBox->dockWidget; addDockWidget(Qt::BottomDockWidgetArea, searchDock); searchDock->setFloating(true); // To be implemented //menu_Display->addAction(searchDock->toggleViewAction()); } void MainWindowImpl::setEditorColor(QColor color) { QVariant red = color.red(); QVariant green = color.green(); QVariant blue = color.blue(); textEdit->setStyleSheet("QTextEdit { background-color: rgb(" + red.toString() + ", " + green.toString() + ", " + blue.toString() + "); color: black; }"); } void MainWindowImpl::setTreeColor(QColor color) { QVariant red = color.red(); QVariant green = color.green(); QVariant blue = color.blue(); treeWidget->setStyleSheet("QTreeWidget { background-color: rgb(" + red.toString() + ", " + green.toString() + ", " + blue.toString() + "); color: black; }"); } /* Apply configuration loaded or modified to the app. */ void MainWindowImpl::applyConfiguration() { setEditorColor(m_confManager->editorColor); setTreeColor(m_confManager->treeColor); if (m_confManager->useTrayIcon) m_trayIcon->show(); else m_trayIcon->hide(); if (mainModel != NULL) mainModel->setDateFormat(m_confManager->dateFormat); } /* Display a warning when file is empty. */ void MainWindowImpl::setEmptyFileDisplay() { textEdit->setHtml(" 

" + tr("This file is empty. Please add root categories and/or pages.") + "

"); } /* Format modifications : implements changes in format. */ /* Apply format changes on text. */ void MainWindowImpl::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { QTextCursor cursor = textEdit->textCursor(); /* Code from the example. Don't find it useful. if (!cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); */ cursor.mergeCharFormat(format); textEdit->mergeCurrentCharFormat(format); } /* Update actions state. Triggered by style change event from QTextEdit. */ void MainWindowImpl::onFontChanged(const QFont &f) { comboFont->setCurrentIndex(comboFont->findText(QFontInfo(f).family())); comboSize->setCurrentIndex(comboSize->findText(QString::number(f.pointSize()))); actionBold->setChecked(f.bold()); actionItalic->setChecked(f.italic()); actionUnderline->setChecked(f.underline()); } /* Update color action drawing. Triggered by style change event from QTextEdit. */ void MainWindowImpl::onColorChanged(const QColor &c) { QPixmap pix(16, 16); pix.fill(c); action_Color->setIcon(pix); } /* Update alignment actions. Triggered by alignment change event from QTextEdit. */ void MainWindowImpl::onAlignmentChanged(Qt::Alignment a) { if (a & Qt::AlignLeft) { actionAlignLeft->setChecked(true); } else if (a & Qt::AlignHCenter) { actionAlignCenter->setChecked(true); } else if (a & Qt::AlignRight) { actionAlignRight->setChecked(true); } else if (a & Qt::AlignJustify) { actionAlignJustify->setChecked(true); } } /* Settings methods. */ void MainWindowImpl::writeSettings() { #ifdef Q_WS_WIN QSettings settings(AppName() + ".ini", QSettings::IniFormat, 0); #else QSettings settings(QSettings::IniFormat, QSettings::UserScope, AppName(), AppName(), 0); #endif settings.beginGroup("MainWindow"); settings.setValue("geometry", this->saveGeometry()); settings.endGroup(); settings.beginGroup("Docks"); settings.setValue("MainDocks", this->saveState()); settings.endGroup(); } void MainWindowImpl::readSettings() { #ifdef Q_WS_WIN QSettings settings(AppName() + ".ini", QSettings::IniFormat, 0); #else QSettings settings(QSettings::IniFormat, QSettings::UserScope, AppName(), AppName(), 0); #endif settings.beginGroup("MainWindow"); this->restoreGeometry(settings.value("geometry").toByteArray()); settings.endGroup(); settings.beginGroup("Docks"); this->restoreState(settings.value("MainDocks").toByteArray()); settings.endGroup(); } /* Events : slots programatically linked. */ void MainWindowImpl::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::DoubleClick: if (isMinimized()) { setWindowState(windowState() & ~Qt::WindowMinimized | Qt::WindowActive); } else if (!isVisible()) { show(); activateWindow(); } else { hide(); } default: ; } } void MainWindowImpl::onActionSysShow() { if (!this->isVisible()) this->show(); this->setWindowState(this->windowState() & ~Qt::WindowMinimized | Qt::WindowActive); } void MainWindowImpl::onActionSysClose() { m_closeFromMenu = true; this->close(); } void MainWindowImpl::onActionMenuMoveUp() { QTreeWidgetItem *current = treeWidget->currentItem(); QTreeWidgetItem *parent = current->parent(); if (parent) { int index1 = parent->indexOfChild(treeWidget->currentItem()); int index2; if (index1 > 0) { index2 = index1 - 1; QTreeWidgetItem *item1 = parent->child(index1); bool expanded1 = item1->isExpanded(); item1 = parent->takeChild(index1); parent->insertChild(index2, item1); item1->setExpanded(expanded1); treeWidget->setCurrentItem(item1); mainModel->setFileModified(true); } } else { int index1 = treeWidget->indexOfTopLevelItem(treeWidget->currentItem()); int index2; if (index1 > 0) { index2 = index1 - 1; QTreeWidgetItem *item1 = treeWidget->topLevelItem(index1); bool expanded1 = item1->isExpanded(); item1 = treeWidget->takeTopLevelItem(index1); treeWidget->insertTopLevelItem(index2, item1); item1->setExpanded(expanded1); treeWidget->setCurrentItem(item1); mainModel->setFileModified(true); } } } void MainWindowImpl::onActionMenuMoveDown() { QTreeWidgetItem *current = treeWidget->currentItem(); QTreeWidgetItem *parent = current->parent(); if (parent) { int index1 = parent->indexOfChild(treeWidget->currentItem()); int index2; if (index1 < (parent->childCount() - 1)) { index2 = index1 + 1; QTreeWidgetItem *item1 = parent->child(index1); bool expanded1 = item1->isExpanded(); item1 = parent->takeChild(index1); parent->insertChild(index2, item1); item1->setExpanded(expanded1); treeWidget->setCurrentItem(item1); mainModel->setFileModified(true); } } else { int index1 = treeWidget->indexOfTopLevelItem(treeWidget->currentItem()); int index2; if (index1 < (treeWidget->topLevelItemCount() - 1)) { index2 = index1 + 1; QTreeWidgetItem *item1 = treeWidget->topLevelItem(index1); bool expanded1 = item1->isExpanded(); item1 = treeWidget->takeTopLevelItem(index1); treeWidget->insertTopLevelItem(index2, item1); item1->setExpanded(expanded1); treeWidget->setCurrentItem(item1); mainModel->setFileModified(true); } } } void MainWindowImpl::onActionMenuMoveRight() { QTreeWidgetItem *current = treeWidget->currentItem(); QTreeWidgetItem *parent = current->parent(); if (parent) { int index = parent->indexOfChild(treeWidget->currentItem()); if (index > 0) { int parentIndex = index - 1; QTreeWidgetItem *newParent; newParent = parent->child(parentIndex); int dataIndex = newParent->data(0, Qt::UserRole).toUInt(); QString type = mainModel->getType(dataIndex); if ((type == "CATEGORY") && (newParent != current)) { QTreeWidgetItem *child = parent->takeChild(index); newParent->addChild(child); treeWidget->setCurrentItem(child); mainModel->setFileModified(true); } } } else { int index = treeWidget->indexOfTopLevelItem(treeWidget->currentItem()); if (index > 0) { int parentIndex = index - 1; QTreeWidgetItem *newParent; newParent = treeWidget->topLevelItem(parentIndex); int dataIndex = newParent->data(0, Qt::UserRole).toUInt(); QString type = mainModel->getType(dataIndex); if ((type == "CATEGORY") && (newParent != current)) { QTreeWidgetItem *child = treeWidget->takeTopLevelItem(index); newParent->addChild(child); treeWidget->setCurrentItem(child); mainModel->setFileModified(true); } } } } void MainWindowImpl::onActionMenuMoveLeft() { QTreeWidgetItem *current = treeWidget->currentItem(); QTreeWidgetItem *parent = current->parent(); int index; if (parent) { index = parent->indexOfChild(treeWidget->currentItem()); QTreeWidgetItem *newParent = parent->parent(); QTreeWidgetItem *moved = parent->takeChild(index); if (newParent) newParent->addChild(moved); else treeWidget->addTopLevelItem(moved); treeWidget->setCurrentItem(moved); mainModel->setFileModified(true); } } void MainWindowImpl::onActionAddRootCategory() { QTreeWidgetItem *childItem; bool ok; QString newName = QInputDialog::getText(this, tr("New root category"), tr("New root category name :"), QLineEdit::Normal, tr("NewCategory"), &ok); if (ok) { int index = mainModel->addItem(newName, "CATEGORY", "", QDateTime::currentDateTime()); childItem = new QTreeWidgetItem(treeWidget); // Setup icons and model. childItem->setIcon(0, mainModel->m_folderIcon); childItem->setText(0, newName); childItem->setData(0, Qt::UserRole, index); treeWidget->setCurrentItem(childItem); onTreeClick(childItem, 0); } } void MainWindowImpl::onActionAddRootPage() { QTreeWidgetItem *childItem; bool ok; QString newName = QInputDialog::getText(this, tr("New root page"), tr("New root page name :"), QLineEdit::Normal, tr("NewPage"), &ok); if (ok) { int index = mainModel->addItem(newName, "PAGE", "", QDateTime::currentDateTime()); childItem = new QTreeWidgetItem(treeWidget); // Setup icons and model. childItem->setIcon(0, mainModel->m_bookmarkIcon); childItem->setText(0, newName); childItem->setData(0, Qt::UserRole, index); treeWidget->setCurrentItem(childItem); onTreeClick(childItem, 0); } } void MainWindowImpl::onActionMenuAddCategory() { QTreeWidgetItem *childItem; QTreeWidgetItem *item = treeWidget->currentItem(); bool ok; QString newName = QInputDialog::getText(this, tr("New category"), tr("New category name :"), QLineEdit::Normal, tr("NewCategory"), &ok); if (ok) { int index = mainModel->addItem(newName, "CATEGORY", "", QDateTime::currentDateTime()); if (item != NULL) { childItem = new QTreeWidgetItem(item); childItem->setFlags(item->flags()); } else childItem = new QTreeWidgetItem(treeWidget); // Setup icons and model. childItem->setIcon(0, mainModel->m_folderIcon); childItem->setText(0, newName); childItem->setData(0, Qt::UserRole, index); treeWidget->setCurrentItem(childItem); onTreeClick(childItem, 0); } } void MainWindowImpl::onActionMenuAddPage() { QTreeWidgetItem *childItem; QTreeWidgetItem *item = treeWidget->currentItem(); bool ok; QString newName = QInputDialog::getText(this, tr("New page"), tr("New page name :"), QLineEdit::Normal, tr("NewPage"), &ok); if (ok) { int index = mainModel->addItem(newName, "PAGE", "", QDateTime::currentDateTime()); if (item != NULL) { childItem = new QTreeWidgetItem(item); childItem->setFlags(item->flags()); } else childItem = new QTreeWidgetItem(treeWidget); // Setup icons and model. childItem->setIcon(0, mainModel->m_bookmarkIcon); childItem->setText(0, newName); childItem->setData(0, Qt::UserRole, index); treeWidget->setCurrentItem(childItem); onTreeClick(childItem, 0); } } void MainWindowImpl::onActionMenuRename() { QTreeWidgetItem *item = treeWidget->currentItem(); if (item != NULL) { int index = item->data(0, Qt::UserRole).toUInt(); QString name = mainModel->getName(index); bool ok; QString newName = QInputDialog::getText(this, tr("Rename"), tr("New name :"), QLineEdit::Normal, name, &ok); if (ok) { mainModel->changeName(index, newName); item->setText(0, newName); } } } void MainWindowImpl::onActionMenuDelete() { QTreeWidgetItem *item = treeWidget->currentItem(); if (item != NULL) { int index = item->data(0, Qt::UserRole).toUInt(); QString name = mainModel->getName(index); QMessageBox::StandardButton ret = QMessageBox::question(this, tr("Delete"), tr("Do you want to delete this item ?"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel); if (ret == QMessageBox::Ok) { // If the deleted item is in the editor, clear it. if (item == mainModel->getCurrentItem()) { textEdit->clear(); textEdit->setEnabled(false); } // Delete the item, but NOT its data in the model, as it will create an offset // with index which will mess up the whole thing ;) delete item; mainModel->setFileModified(true); } } } void MainWindowImpl::onActionMenuProperty() { QTreeWidgetItem *item = treeWidget->currentItem(); if (item != NULL) { int index = item->data(0, Qt::UserRole).toUInt(); PropertyDlgImpl *propertyDlg = new PropertyDlgImpl(this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); propertyDlg->setupData(m_confManager->dateFormat, mainModel->getName(index), mainModel->getType(index), mainModel->getCreationDate(index)); propertyDlg->exec(); delete propertyDlg; } } /* When selecting a new item, update enabled state of "move" actions. A bit messy, but it work. */ void MainWindowImpl::onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) { if (mainModel != NULL) { QTreeWidgetItem *item = current; if (item != NULL) { actionMenuProperty->setEnabled(true); int index = item->data(0, Qt::UserRole).toUInt(); QString type = mainModel->getType(index); if (type == "PAGE") { actionMenuAddPage->setEnabled(false); actionMenuAddCategory->setEnabled(false); actionMenuRename->setEnabled(true); actionMenuDelete->setEnabled(true); } else if (type == "CATEGORY") { actionMenuAddPage->setEnabled(true); actionMenuAddCategory->setEnabled(true); actionMenuRename->setEnabled(true); actionMenuDelete->setEnabled(true); } QTreeWidgetItem *parent = item->parent(); QTreeWidgetItem *upParent; int index1; int index2; int count1; if (parent) { actionMenuMoveLeft->setEnabled(true); index1 = parent->indexOfChild(item); count1 = parent->childCount(); if (index1 > 0) { upParent = parent->child(index1 - 1); index2 = parent->indexOfChild(upParent); int dataIndex = upParent->data(0, Qt::UserRole).toUInt(); QString type = mainModel->getType(dataIndex); if (type == "CATEGORY") actionMenuMoveRight->setEnabled(true); else actionMenuMoveRight->setEnabled(false); } else actionMenuMoveRight->setEnabled(false); } else { actionMenuMoveLeft->setEnabled(false); index1 = treeWidget->indexOfTopLevelItem(item); count1 = treeWidget->topLevelItemCount(); if (index1 > 0) { upParent = treeWidget->topLevelItem(index1 - 1); index2 = treeWidget->indexOfTopLevelItem(upParent); int dataIndex = upParent->data(0, Qt::UserRole).toUInt(); QString type = mainModel->getType(dataIndex); if (type == "CATEGORY") actionMenuMoveRight->setEnabled(true); else actionMenuMoveRight->setEnabled(false); } else actionMenuMoveRight->setEnabled(false); } if (index1 == 0) actionMenuMoveUp->setEnabled(false); else actionMenuMoveUp->setEnabled(true); if (index1 == (count1 - 1)) actionMenuMoveDown->setEnabled(false); else actionMenuMoveDown->setEnabled(true); } else { actionAddRootCategory->setEnabled(true); actionAddRootPage->setEnabled(true); actionMenuProperty->setEnabled(false); actionMenuAddPage->setEnabled(false); actionMenuAddCategory->setEnabled(false); actionMenuRename->setEnabled(false); actionMenuDelete->setEnabled(false); actionMenuMoveUp->setEnabled(false); actionMenuMoveDown->setEnabled(false); actionMenuMoveLeft->setEnabled(false); actionMenuMoveRight->setEnabled(false); } } else { actionAddRootCategory->setEnabled(false); actionAddRootPage->setEnabled(false); actionMenuProperty->setEnabled(false); actionMenuAddPage->setEnabled(false); actionMenuAddCategory->setEnabled(false); actionMenuRename->setEnabled(false); actionMenuDelete->setEnabled(false); actionMenuMoveUp->setEnabled(false); actionMenuMoveDown->setEnabled(false); actionMenuMoveLeft->setEnabled(false); actionMenuMoveRight->setEnabled(false); } } /* Display the popup menu on the treeview. */ void MainWindowImpl::onTreeContextMenuRequested(QPoint pos) { if (mainModel != NULL) { onTreeClick(treeWidget->itemAt(pos), 0); contextMenu->exec(QCursor::pos()); } } /* Click on TreeWidget : update the editor if necessary. */ void MainWindowImpl::onTreeClick(QTreeWidgetItem *treeItem, int col) { if ((treeItem != NULL) && (mainModel != NULL)) { mainModel->updateDisplay(treeItem); setEditorColor(m_confManager->editorColor); // Font QString font = m_confManager->defaultFont; int fontIndex = comboFont->findText(font); if (fontIndex != -1) { comboFont->setCurrentIndex(fontIndex); onTextFamily(font); } // Font size QString fontSize = m_confManager->defaultFontSize; int fontSizeIndex = comboSize->findText(fontSize); if (fontSizeIndex != -1) { comboSize->setCurrentIndex(fontSizeIndex); onTextSize(fontSize); } // Font color QTextCharFormat fmt; fmt.setForeground(m_confManager->defaultFontColor); mergeFormatOnWordOrSelection(fmt); onColorChanged(m_confManager->defaultFontColor); } } /* Close the application. */ void MainWindowImpl::doClose() { if (mainModel != NULL) m_confManager->lastFile = mainModel->getFileName(); else m_confManager->lastFile = ""; m_trayIcon->hide(); writeSettings(); delete mainModel; delete m_confManager; // Will save configuration. delete m_styleManager; // Will save styles. } /* Hide the application to tray. */ void MainWindowImpl::doCloseToTray() { this->hide(); if (m_confManager->showMessageOnCloseToTray) m_trayIcon->showMessage(AppDisplayName(), AppDisplayName() + tr(" has been minimized to tray.\nYou can show it by double-clicking on its icon."), QSystemTrayIcon::MessageIcon(QSystemTrayIcon::Information), 5000); } /* Close request. */ void MainWindowImpl::closeEvent(QCloseEvent *event) { // m_closeFromMenu equals true when user has clicked on any of the quit menu, // but equals false when closing using top right window button. if ((m_closeFromMenu) || (!m_confManager->useTrayIcon) || ((m_confManager->useTrayIcon) && (!m_confManager->closeToTray))) { m_closeFromMenu = false; if (mainModel != NULL) { if (mainModel->askForSaveAndSave(this)) { event->accept(); doClose(); } else event->ignore(); } else { event->accept(); doClose(); } } else { event->ignore(); doCloseToTray(); } } /* Alignement actions triggered : change alignment. */ void MainWindowImpl::onTextAlign(QAction *a) { if (a == actionAlignLeft) textEdit->setAlignment(Qt::AlignLeft); else if (a == actionAlignCenter) textEdit->setAlignment(Qt::AlignHCenter); else if (a == actionAlignRight) textEdit->setAlignment(Qt::AlignRight); else if (a == actionAlignJustify) textEdit->setAlignment(Qt::AlignJustify); } /* Font combo change. */ void MainWindowImpl::onTextFamily(const QString &f) { QTextCharFormat fmt; fmt.setFontFamily(f); mergeFormatOnWordOrSelection(fmt); textEdit->setFontFamily(f); textEdit->setFocus(); } /* Font size change. */ void MainWindowImpl::onTextSize(const QString &p) { QTextCharFormat fmt; fmt.setFontPointSize(p.toFloat()); mergeFormatOnWordOrSelection(fmt); textEdit->setFontPointSize(p.toFloat()); textEdit->setFocus(); } /* Events : Automaticaly generated by QDevelop */ void MainWindowImpl::onClipboardDataChanged() { actionPaste->setEnabled(!QApplication::clipboard()->text().isEmpty()); } void MainWindowImpl::on_action_Quit_triggered() { m_closeFromMenu = true; this->close(); } void MainWindowImpl::openFile(QString fileName) { // Delete old model. if (mainModel != NULL) delete mainModel; // Create new model and open the file. mainModel = new Model(treeWidget, textEdit, fileName, m_confManager->dateFormat); if (mainModel->open()) { actionAddRootCategory->setEnabled(true); actionAddRootPage->setEnabled(true); statusBar()->showMessage(tr("File opened : ") + mainModel->getFileName()); } else { // Create an empty file. delete mainModel; mainModel = NULL; on_action_New_triggered(); statusBar()->showMessage(tr("File not found.")); } } /* Open a file. */ void MainWindowImpl::on_action_Open_triggered() { bool ret; // If a file is already opened, check if the user cant to save it, if its not. if (mainModel != NULL) ret = mainModel->askForSaveAndSave(this); else ret = true; if (ret) { // Ask for filename. QString fileName = QFileDialog::getOpenFileName(this, tr("Open a file"), QDir::currentPath(), tr("XML Files (*.xml);;All files (*.*)")); if (fileName.isEmpty()) return; openFile(fileName); } } /* Create a new file. */ void MainWindowImpl::on_action_New_triggered() { bool ret; // If a file is already opened, check if the user cant to save it, if its not. if (mainModel != NULL) ret = mainModel->askForSaveAndSave(this); else ret = true; if (ret) { // Delete old model. if (mainModel != NULL) delete mainModel; // Create a new one. mainModel = new Model(treeWidget, textEdit, "", m_confManager->dateFormat); mainModel->setFileModified(false); actionAddRootCategory->setEnabled(true); actionAddRootPage->setEnabled(true); setEmptyFileDisplay(); statusBar()->showMessage(tr("New file.")); } } /* Save current file. */ void MainWindowImpl::on_action_Save_triggered() { if (mainModel != NULL) { if (mainModel->getFileName().isEmpty()) { on_actionSave_as_triggered(); } else { mainModel->save(); statusBar()->showMessage(tr("File saved : ") + mainModel->getFileName()); } } } /* Save current file under a new name. */ void MainWindowImpl::on_actionSave_as_triggered() { if (mainModel != NULL) { // Ask for name. QString fileName = QFileDialog::getSaveFileName(this, tr("Save a file"), QDir::currentPath(), tr("XML Files (*.xml);;All files (*.*)")); if (fileName.isEmpty()) return; mainModel->saveAs(fileName); statusBar()->showMessage(tr("File saved as : ") + mainModel->getFileName()); } } /* Editor actions. */ void MainWindowImpl::on_actionBold_triggered() { QTextCharFormat fmt; fmt.setFontWeight(actionBold->isChecked() ? QFont::Bold : QFont::Normal); mergeFormatOnWordOrSelection(fmt); } void MainWindowImpl::on_actionItalic_triggered() { QTextCharFormat fmt; fmt.setFontItalic(actionItalic->isChecked()); mergeFormatOnWordOrSelection(fmt); } void MainWindowImpl::on_actionUnderline_triggered() { QTextCharFormat fmt; fmt.setFontUnderline(actionUnderline->isChecked()); mergeFormatOnWordOrSelection(fmt); } void MainWindowImpl::on_textEdit_currentCharFormatChanged(QTextCharFormat format) { onFontChanged(format.font()); onColorChanged(format.foreground().color()); } void MainWindowImpl::on_action_Color_triggered() { QColor col = QColorDialog::getColor(textEdit->textColor(), this); if (!col.isValid()) return; QTextCharFormat fmt; fmt.setForeground(col); mergeFormatOnWordOrSelection(fmt); onColorChanged(col); } void MainWindowImpl::on_textEdit_cursorPositionChanged() { onAlignmentChanged(textEdit->alignment()); } /* Misc. actions. */ void MainWindowImpl::on_actionAbout_Qt_triggered() { QMessageBox::aboutQt(this, AppDisplayName()); } void MainWindowImpl::on_action_About_triggered() { AboutDialogImpl *aboutDlg = new AboutDialogImpl(this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); aboutDlg->setData(AppDisplayName(), AppVersion()); aboutDlg->exec(); delete aboutDlg; //QMessageBox::about(this, AppDisplayName(), tr("

About ") + AppDisplayName() + "

" + AppDisplayName() + tr(" is a note-taking application. Each note can be classified in categories.

It is released under the terms of GPL v2 (See LICENSE file).

") + AppDisplayName() + tr(" is made with Qt under QDevelop.

Version ") + AppVersion() + "

"); } void MainWindowImpl::on_actionPrint_triggered() { if ((mainModel != NULL) && (mainModel->getCurrentItem() != NULL)) { QTextDocument *document = textEdit->document(); QPrinter printer; QPrintDialog *dialog = new QPrintDialog(&printer, this); dialog->setWindowTitle(tr("Print Document")); if (dialog->exec() != QDialog::Accepted) return; document->print(&printer); } } void MainWindowImpl::on_actionExport_PDF_triggered() { if ((mainModel != NULL) && (mainModel->getCurrentItem() != NULL)) { QString fileName = QFileDialog::getSaveFileName(this, tr("Export PDF"), QString(), "*.pdf"); if (!fileName.isEmpty()) { if (QFileInfo(fileName).suffix().isEmpty()) fileName.append(".pdf"); QPrinter printer(QPrinter::HighResolution); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(fileName); textEdit->document()->print(&printer); } } } void MainWindowImpl::on_actionPostScript_triggered() { if ((mainModel != NULL) && (mainModel->getCurrentItem() != NULL)) { QString fileName = QFileDialog::getSaveFileName(this, tr("Export PostScript"), QString(), "*.ps"); if (!fileName.isEmpty()) { if (QFileInfo(fileName).suffix().isEmpty()) fileName.append(".ps"); QPrinter printer(QPrinter::HighResolution); printer.setOutputFormat(QPrinter::PostScriptFormat); printer.setOutputFileName(fileName); textEdit->document()->print(&printer); } } } void MainWindowImpl::on_actionStyle_editor_triggered() { StyleEditorImpl *styleEditor = new StyleEditorImpl(this, 0); styleEditor->setManagers(m_confManager, m_styleManager); styleEditor->exec(); delete styleEditor; m_styleManager->updateComboStyle(comboStyle); } void MainWindowImpl::on_action_Apply_current_style_triggered() { if ((comboStyle->count() > 0) && (textEdit->isEnabled())) { int index = comboStyle->itemData(comboStyle->currentIndex(), Qt::UserRole).toUInt(); // Font QString font = m_styleManager->getStyleFont(index); int fontIndex = comboFont->findText(font); if (fontIndex != -1) { comboFont->setCurrentIndex(fontIndex); onTextFamily(font); } // Font size QString fontSize = m_styleManager->getStyleSize(index); int fontSizeIndex = comboSize->findText(fontSize); if (fontSizeIndex != -1) { comboSize->setCurrentIndex(fontSizeIndex); onTextSize(fontSize); } // Font color QTextCharFormat fmt; fmt.setForeground(m_styleManager->getStyleColor(index)); mergeFormatOnWordOrSelection(fmt); onColorChanged(m_styleManager->getStyleColor(index)); // Bold, Italic, Underline actionBold->setChecked(m_styleManager->getStyleBold(index)); on_actionBold_triggered(); actionItalic->setChecked(m_styleManager->getStyleItalic(index)); on_actionItalic_triggered(); actionUnderline->setChecked(m_styleManager->getStyleUnderline(index)); on_actionUnderline_triggered(); // Alignment switch (m_styleManager->getStyleAlignment(index)) { case 0 : actionAlignLeft->setChecked(true); onTextAlign(actionAlignLeft); break; case 1 : actionAlignCenter->setChecked(true); onTextAlign(actionAlignCenter); break; case 2 : actionAlignRight->setChecked(true); onTextAlign(actionAlignRight); break; case 3 : actionAlignJustify->setChecked(true); onTextAlign(actionAlignJustify); break; default : actionAlignLeft->setChecked(true); onTextAlign(actionAlignLeft); break; } } } void MainWindowImpl::on_action_Options_triggered() { ConfigurationDlgImpl *confEditor = new ConfigurationDlgImpl(this, 0); confEditor->setConfigurationManager(m_confManager); int result = confEditor->exec(); if (result == QDialog::Accepted) applyConfiguration(); delete confEditor; } void MainWindowImpl::on_action_Search_triggered() { QMessageBox::information(this, tr("Search"), tr("Coming soon...")); }