Beispiel #1
0
// Handle what happens when something is dropped onto a tag item
bool NNotebookView::dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) {
    Q_UNUSED(index); // suppress unused variable
    Q_UNUSED(action); // suppress unused variable

    // If this is a note-to-tag drop we are assigning tags to a note
    if (data->hasFormat("application/x-nixnote-note")) {
        QByteArray d = data->data("application/x-nixnote-note");
        QString data(d);

        // Find the tag lid we dropped onto
        qint32 bookLid = parent->data(NAME_POSITION, Qt::UserRole).toInt();
        if (bookLid <=0)
            return false;
        NotebookTable bookTable(global.db);
        Notebook notebook;
        bookTable.get(notebook, bookLid);

        // The string has a long list of note lids.  We parse them out & update the note
        QStringList stringLids = data.split(" ");
        for (int i=0; i<stringLids.size(); i++) {
            if (stringLids[i].trimmed() != "") {
                qint32 noteLid = stringLids.at(i).toInt();
                if (noteLid > 0) {
                    NoteTable noteTable(global.db);
                    qint32 currentNotebook = noteTable.getNotebookLid(noteLid);
                    if (currentNotebook != bookLid) {
                        noteTable.updateNotebook(noteLid, bookLid, true);
                        emit(updateNoteList(noteLid, NOTE_TABLE_NOTEBOOK_POSITION, notebook.name.value()));
                        qint64 dt = QDateTime::currentMSecsSinceEpoch();
                        noteTable.updateDate(noteLid,  dt, NOTE_UPDATED_DATE, true);
                        emit(updateNoteList(noteLid, NOTE_TABLE_DATE_UPDATED_POSITION, dt));
                    }
                }
            }
        }
        if (stringLids.size() > 0) {
            emit(updateCounts());
        }
        return true;
    }


    return false;
}
Beispiel #2
0
// Delete an item from the tree.  We really just hide it.
void NTagView::mergeRequested() {
    QList<QTreeWidgetItem*> items = selectedItems();

    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText(tr("Are you sure you want to merge these tags?"));
    msgBox.setWindowTitle(tr("Verify Merge"));
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::No);
    int ret = msgBox.exec();
    if (ret == QMessageBox::No)
        return;

    qint32 lid = items[0]->data(NAME_POSITION, Qt::UserRole).toInt();
    NoteTable ntable(global.db);
    QList<qint32> notes;
    for (int j=1; j<items.size(); j++) {
        ntable.findNotesByTag(notes, items[j]->data(NAME_POSITION, Qt::UserRole).toInt());
        for (int i=0; i<notes.size(); i++) {
            if (!ntable.hasTag(notes[i], lid)) {
                ntable.addTag(notes[i], lid, true);
                QString tagString = ntable.getNoteListTags(notes[i]);
                emit(updateNoteList(notes[i], NOTE_TABLE_TAGS_POSITION, tagString));
                qint64 dt = QDateTime::currentMSecsSinceEpoch();
                ntable.updateDate(notes[i],  dt, NOTE_UPDATED_DATE, true);
                emit(updateNoteList(notes[i], NOTE_TABLE_DATE_UPDATED_POSITION, dt));
            }
        }
    }

    // Now delete the old tags.
    for (int i=1; i<items.size(); i++) {
        qint32 lid = items[i]->data(NAME_POSITION, Qt::UserRole).toInt();
        TagTable table(global.db);
        table.deleteTag(lid);

        // Now remove it in the datastore
        NTagViewItem *ptr = dataStore.take(items[i]->data(NAME_POSITION, Qt::UserRole).toInt());
        emit(tagDeleted(lid, ptr->data(NAME_POSITION, Qt::DisplayRole).toString()));
        delete ptr;
    }
}
Beispiel #3
0
// Add a new note to the database
qint32 NoteTable::add(qint32 l, Note &t, bool isDirty) {
    QLOG_DEBUG() << "Adding note: " << QString::fromStdString(t.title);
    ResourceTable resTable;
    ConfigStore cs;
    QSqlQuery query;
    qint32 position;
    TagScanner scanner;
    qint32 lid = l;
    qint32 notebookLid;

    query.prepare("Insert into DataStore (lid, key, data) values (:lid, :key, :data)");
    if (lid <= 0)
        lid = cs.incrementLidCounter();

    query.bindValue(":lid", lid);
    query.bindValue(":key", NOTE_GUID);
    query.bindValue(":data", QString::fromStdString(t.guid));
    query.exec();

    query.bindValue(":lid", lid);
    query.bindValue(":key", NOTE_INDEX_NEEDED);
    query.bindValue(":data", true);
    query.exec();

    if (t.__isset.title) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_TITLE);
        query.bindValue(":data", QString::fromStdString(t.title.c_str()));
        query.exec();
    }

    if (t.__isset.content) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_CONTENT);
        QByteArray b;
        b.append(QString::fromStdString(t.content).toAscii());
        query.bindValue(":data", b);
        query.exec();
    }

    if (t.__isset.contentHash) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_CONTENT_HASH);
        query.bindValue(":data", QString::fromStdString(t.contentHash));
        query.exec();
    }

    if (t.__isset.contentLength) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_CONTENT_LENGTH);
        query.bindValue(":data", t.contentLength);
        query.exec();
    }

    query.bindValue(":lid", lid);
    query.bindValue(":key", NOTE_UPDATE_SEQUENCE_NUMBER);
    query.bindValue(":data", t.updateSequenceNum);
    query.exec();

    query.bindValue(":lid", lid);
    query.bindValue(":key", NOTE_ISDIRTY);
    query.bindValue(":data", isDirty);
    query.exec();

    if (t.__isset.created) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_CREATED_DATE);
        query.bindValue(":data", QVariant::fromValue(t.created));
        query.exec();
    }

    if (t.__isset.updated) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_UPDATED_DATE);
        query.bindValue(":data", QVariant::fromValue(t.updated));
        query.exec();
    }

    if (t.__isset.deleted) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_DELETED_DATE);
        query.bindValue(":data", QVariant::fromValue(t.deleted));
        query.exec();
    }

    if (t.__isset.active) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_ACTIVE);
        query.bindValue(":data", QVariant::fromValue(t.active));
        query.exec();
    }

    if (t.__isset.notebookGuid) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_NOTEBOOK_LID);
        NotebookTable notebookTable;
        notebookLid = notebookTable.getLid(QString::fromStdString(t.notebookGuid));

        // If not found, we insert one to avoid problems.  We'll probably get the real data later
        if (notebookLid == 0) {
            notebookLid = cs.incrementLidCounter();
            Notebook notebook;
            notebook.guid = t.notebookGuid;
            notebook.name = "";
            notebook.__isset.guid = true;
            notebook.__isset.name = true;
            notebookTable.add(notebookLid, notebook, false, false);
        }
        query.bindValue(":data", notebookLid);
        query.exec();
    }

    for (unsigned int i=0; t.__isset.tagGuids && i<t.tagGuids.size(); i++) {
        TagTable tagTable;
        qint32 tagLid = tagTable.getLid(t.tagGuids.at(i));
        if (tagLid == 0) {
            // create a dummy tag to avoid later problems
            Tag newTag;
            newTag.guid = t.tagGuids.at(i);
            newTag.name = "";
            newTag.__isset.guid = true;
            newTag.__isset.name = true;
            tagLid = cs.incrementLidCounter();
            tagTable.add(tagLid, newTag, false, 0);
        }

        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_TAG_LID);
        query.bindValue(":data", tagLid);
        query.exec();
    }

    for (unsigned int i=0; t.__isset.resources && i<t.resources.size(); i++) {
        qint32 resLid;
        Resource *r;
        r = &t.resources[i];
        resLid = resTable.getLid(t.guid,t.resources[i].guid);
        if (resLid == 0)
            resLid = cs.incrementLidCounter();
        resTable.add(resLid, t.resources[i], isDirty);

        if (r->__isset.mime) {
            QString mime = QString::fromStdString(r->mime);
            if (!mime.startsWith("image/") && mime != "vnd.evernote.ink") {
                query.bindValue(":lid", lid);
                query.bindValue(":key", NOTE_HAS_ATTACHMENT);
                query.bindValue(":data", true);
                query.exec();
            }
        }
    }

    if (t.__isset.attributes) {
        if (t.attributes.__isset.subjectDate) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_SUBJECT_DATE);
            query.bindValue(":data", QVariant::fromValue(t.attributes.subjectDate));
            query.exec();
        }
        if (t.attributes.__isset.latitude) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_LATITUDE);
            query.bindValue(":data", QVariant::fromValue(t.attributes.latitude));
            query.exec();
        }
        if (t.attributes.__isset.latitude) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_LONGITUDE);
            query.bindValue(":data", QVariant::fromValue(t.attributes.longitude));
            query.exec();
        }
        if (t.attributes.__isset.altitude) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_ALTITUDE);
            query.bindValue(":data", QVariant::fromValue(t.attributes.altitude));
            query.exec();
        }
        if (t.attributes.__isset.author) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_AUTHOR);
            query.bindValue(":data", QString::fromStdString(t.attributes.author));
            query.exec();
        }
        if (t.attributes.__isset.source) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE);
            query.bindValue(":data", QString::fromStdString(t.attributes.source));
            query.exec();
        }
        if (t.attributes.__isset.sourceURL) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE_URL);
            query.bindValue(":data", QString::fromStdString(t.attributes.sourceURL));
            query.exec();
        }
        if (t.attributes.__isset.sourceApplication) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE_APPLICATION);
            query.bindValue(":data", QString::fromStdString(t.attributes.sourceApplication));
            query.exec();
        }
        if (t.attributes.__isset.shareDate) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_SHARE_DATE);
            query.bindValue(":data",QVariant::fromValue(t.attributes.shareDate));
            query.exec();
        }
        if (t.attributes.__isset.placeName) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_PLACE_NAME);
            query.bindValue(":data", QString::fromStdString(t.attributes.placeName));
            query.exec();
        }
        if (t.attributes.__isset.contentClass) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_ATTRIBUTE_CONTENT_CLASS);
            query.bindValue(":data", QString::fromStdString(t.attributes.contentClass));
            query.exec();
        }
    }

    // No determine some attributes of the note based upon the content
    // This should probably happen every time a note changes? Or at least something simular:
    QString content;
    if (t.__isset.content)
        content = QString::fromStdString(t.content);
    else
        content = "";

    position = content.indexOf("<en-crypt");
    if (position > 0) {
        query.bindValue(":lid", lid);
        query.bindValue(":key", NOTE_HAS_ENCRYPT);
        query.bindValue(":data", true);
        query.exec();
    }
    position = content.indexOf("<en-todo");
    if (position > 0) {
        position = content.indexOf("<en-todo checked=\"true\"");
        if (position > 0) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_HAS_TODO_COMPLETED);
            query.bindValue(":data", true);
            query.exec();
        }
        position = qMax(content.indexOf("<en-todo checked=\"false\""), content.indexOf("<en-todo>"));
        if (position > 0) {
            query.bindValue(":lid", lid);
            query.bindValue(":key", NOTE_HAS_TODO_UNCOMPLETED);
            query.bindValue(":data", true);
            query.exec();
        }
    }

    updateNoteList(lid, t, isDirty);
    return lid;
}
Beispiel #4
0
qint32 NoteTable::duplicateNote(qint32 oldLid) {
    ConfigStore cs;
    qint32 newLid = cs.incrementLidCounter();

    QSqlQuery query;
    QString tempTableName = "notecopy" + QString::number(oldLid);
    query.exec("drop temporary table " +tempTableName);
    query.prepare("create temporary table " +tempTableName +" as select * from datastore where lid=:oldLid");
    query.bindValue(":oldLid", oldLid);
    query.exec();

    query.prepare("Update " +tempTableName +" set lid=:newLid");
    query.bindValue(":newLid", newLid);
    query.exec();

    query.exec("insert into datastore select lid, key, data from " +tempTableName);
    query.exec("drop " +tempTableName);

    query.prepare("update datastore set data=:data where lid=:lid and key=:key");
    query.bindValue(":data", 0);
    query.bindValue(":lid", newLid);
    query.bindValue(":key", NOTE_UPDATE_SEQUENCE_NUMBER);
    query.exec();

    Note n;
    get(n, newLid, false,false);
    updateNoteList(newLid, n, true);

    setDirty(newLid, true);

    // Update all the resources
    ResourceTable resTable;
    QList<qint32> lids;
    resTable.getResourceList(lids, oldLid);
    for (int i=0; i<lids.size(); i++) {
        qint32 newResLid = cs.incrementLidCounter();
        query.prepare("create temporary table " +tempTableName +" as select * from datastore where lid=:oldLid");
        query.bindValue(":oldLid", lids[i]);
        query.exec();


        query.prepare("Update " +tempTableName +" set lid=:newLid");
        query.bindValue(":newLid", newResLid);
        query.exec();

        query.exec("insert into datastore select lid, key, data from " +tempTableName);
        query.exec("drop " +tempTableName);

        query.prepare("update datastore set data=:data where lid=:lid and key=:key");
        query.bindValue(":data", 0);
        query.bindValue(":lid", newResLid);
        query.bindValue(":key", RESOURCE_UPDATE_SEQUENCE_NUMBER);
        query.exec();

        query.prepare("update datastore set data=:data where lid=:lid and key=:key");
        query.bindValue(":data", 0);
        query.bindValue(":lid", newResLid);
        query.bindValue(":key", RESOURCE_NOTE_LID);
        query.exec();

        QStringList filter;
        QDir resDir(global.fileManager.getDbaDirPath());
        filter << QString::number(lids[i])+".*";
        QStringList files = resDir.entryList(filter);
        for (int j=0; j<files.size(); j++) {
            QFile file(global.fileManager.getDbaDirPath()+files[j]);
            int pos = files[j].indexOf(".");
            QString type = files[j].mid(pos);
            file.open(QIODevice::ReadOnly);
            file.copy(global.fileManager.getDbaDirPath()+
                      QString::number(newResLid) +type);
            file.close();
        }
    }

    return newLid;
}
Beispiel #5
0
// Handle what happens when something is dropped onto a tag item
bool NTagView::dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action) {

    // If this is a note-to-tag drop we are assigning tags to a note
    if (data->hasFormat("application/x-nixnote-note")) {
        QByteArray d = data->data("application/x-nixnote-note");
        QString data(d);

        // Find the tag lid we dropped onto
        qint32 tagLid = parent->data(NAME_POSITION, Qt::UserRole).toInt();

        // The string has a long list of note lids.  We parse them out & update the note
        QStringList stringLids = data.split(" ");
        for (int i=0; i<stringLids.size(); i++) {
            if (stringLids[i].trimmed() != "") {
                qint32 noteLid = stringLids.at(i).toInt();
                if (noteLid > 0) {
                    NoteTable noteTable(global.db);
                    if (!noteTable.hasTag(noteLid, tagLid)) {
                        noteTable.addTag(noteLid, tagLid, true);
                        QString tagString = noteTable.getNoteListTags(noteLid);
                        emit(updateNoteList(noteLid, NOTE_TABLE_TAGS_POSITION, tagString));
//                        qint64 dt = QDateTime::currentMSecsSinceEpoch();
//                        noteTable.updateDate(noteLid,  dt, NOTE_UPDATED_DATE, true);
//                        emit(updateNoteList(noteLid, NOTE_TABLE_DATE_UPDATED_POSITION, dt));
                    }
                }
            }
        }
        if (stringLids.size() > 0)
            emit updateCounts();
        return true;
    }
    // If this is a tag-to-tag drop then we are modifying the hierarchy
    if (data->hasFormat("application/x-nixnote-tag")) {

        // If there is no parent, then they are trying to drop to the top level, which isn't permitted
        if (parent == NULL)
            return false;

        // Get the lid we are dropping.
        QByteArray d = data->data("application/x-nixnote-tag");
        qint32 lid = d.toInt();
        if (lid == 0)
            return false;

        qint32 newParentLid = parent->data(NAME_POSITION, Qt::UserRole).toInt();
        qint32 oldParentLid = dataStore[lid]->parentLid;
        if (newParentLid == oldParentLid)
            return false;
        if (newParentLid == lid)
            return false;
        NTagViewItem *item = dataStore[lid];

        // If we had an old parent, remove the child from it.
        if (oldParentLid > 0)  {
            NTagViewItem *parent_ptr = dataStore[oldParentLid];
            for (int i=0; i<parent_ptr->childrenLids.size(); i++) {
                if (parent_ptr->childrenLids[i] == lid) {
                    parent_ptr->childrenLids.removeAt(i);
                    i=parent_ptr->childrenLids.size();
                }
            }
            parent_ptr->removeChild(item);
        } else {
            root->removeChild(item);
        }

        // Update the actual database
        Tag tag;
        TagTable tagTable(global.db);
        tagTable.get(tag, lid);
        QString guid;
        tagTable.getGuid(guid, newParentLid);
        tag.parentGuid = guid;
        tagTable.update(tag, true);

        if (newParentLid>0) {
            NTagViewItem *parent_ptr = dataStore[newParentLid];
            parent_ptr->addChild(item);
            parent_ptr->childrenLids.append(lid);
            item->parentLid = newParentLid;
            item->parentGuid = tag.guid;
        } else {
            item->parentLid = 0;
            item->parentGuid = "";
            root->addChild(item);
        }

        // Resort the data
        this->sortByColumn(NAME_POSITION, Qt::AscendingOrder);
        sortItems(NAME_POSITION, Qt::AscendingOrder);
        return QTreeWidget::dropMimeData(parent, index, data, action);
    }


    return false;
}
Beispiel #6
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
	// open database connection
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("/Users/jdoud/dev/brainstorm.sqlite");
	if(!db.open())
	{
		qDebug() << db.lastError();
		qFatal("Failed to connect.");
	}

	// setup UI
    ui->setupUi(this);
	ui->toolBar->addWidget(ui->comboFonts);
	ui->toolBar->addWidget(ui->comboFontSizes);
	ui->toolBar->addWidget(ui->comboColors);

	// set text editor defaults
	ui->textNote->document()->setIndentWidth(20);
	ui->textNote->setTabStopWidth(20);
	ui->textNote->setTabChangesFocus(false);
	ui->actionIncrease_Indent->setShortcut(Qt::Key_Tab);
	ui->actionDecrease_Indent->setShortcut(Qt::Key_Backtab);

	// setup comboColors
	QPixmap pix(16, 16);
	pix.fill(Qt::white);
	ui->comboColors->addItem(pix, "");
	pix.fill(Qt::black);
	ui->comboColors->addItem(pix, "");
	pix.fill(Qt::red);
	ui->comboColors->addItem(pix, "");
	pix.fill(Qt::blue);
	ui->comboColors->addItem(pix, "");
	pix.fill(Qt::darkGreen);
	ui->comboColors->addItem(pix, "");
	pix.fill(Qt::gray);
	ui->comboColors->addItem(pix, "");


	// create system tray icon
	createActions();
	createTrayIcon();

	// create models
    categoriesModel = new QSqlTableModel();
	categoriesModel->setTable("categories");
	categoriesModel->setSort(1, Qt::AscendingOrder);
	categoriesModel->select();
	ui->listCategories->setModel(categoriesModel);
	ui->listCategories->setModelColumn(1);

    notesModel = new QSqlTableModel();
	notesModel->setTable("notes");
	ui->listNotes->setModel(notesModel);
	ui->listNotes->setModelColumn(2);

    // set splitter size
    QList<int> sizes;
    sizes << 230 << 150;
    ui->splitterLists->setSizes(sizes);
    sizes.clear();
    sizes << 230 << 600;
    ui->splitterNote->setSizes(sizes);

    // connect File menu slots
    connect(ui->actionNew_Category, SIGNAL(triggered()), this, SLOT(newCategory()));
    connect(ui->actionRename_Category, SIGNAL(triggered()), this, SLOT(renameCategory()));
    connect(ui->actionDelete_Category, SIGNAL(triggered()), this, SLOT(deleteCategory()));
    connect(ui->actionNew_Note, SIGNAL(triggered()), this, SLOT(newNote()));
    connect(ui->actionRename_Note, SIGNAL(triggered()), this, SLOT(renameNote()));
    connect(ui->actionSave_Note, SIGNAL(triggered()), this, SLOT(saveNote()));
    connect(ui->actionDelete_Note, SIGNAL(triggered()), this, SLOT(deleteNote()));
    connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(quit()));
    // connect Edit menu slots	
    connect(ui->actionFind_Replace, SIGNAL(triggered()), this, SLOT(findAndReplace()));
    // connect Format menu slots
    connect(ui->actionBold, SIGNAL(triggered()), this, SLOT(bold()));
    connect(ui->actionItalic, SIGNAL(triggered()), this, SLOT(italic()));
    connect(ui->actionUnderline, SIGNAL(triggered()), this, SLOT(underline()));
    connect(ui->actionStrikethrough, SIGNAL(triggered()), this, SLOT(strikethrough()));
    connect(ui->actionBullet_List, SIGNAL(triggered()), this, SLOT(bulletList()));
    connect(ui->actionNumber_List, SIGNAL(triggered()), this, SLOT(numberList()));
    connect(ui->actionIncrease_Indent, SIGNAL(triggered()), this, SLOT(increaseIndent()));
    connect(ui->actionDecrease_Indent, SIGNAL(triggered()), this, SLOT(decreaseIndent()));
    connect(ui->actionShow_Colors, SIGNAL(triggered()), this, SLOT(showColors()));
    connect(ui->actionShow_Fonts, SIGNAL(triggered()), this, SLOT(showFonts()));
    connect(ui->actionIncrease_Font, SIGNAL(triggered()), this, SLOT(increaseFont()));
    connect(ui->actionDecrease_Font, SIGNAL(triggered()), this, SLOT(decreaseFont()));
    connect(ui->actionReset_Font, SIGNAL(triggered()), this, SLOT(resetFont()));
    connect(ui->actionAlign_Left, SIGNAL(triggered()), this, SLOT(alignLeft()));
    connect(ui->actionAlign_Center, SIGNAL(triggered()), this, SLOT(alignCenter()));
    connect(ui->actionAlign_Right, SIGNAL(triggered()), this, SLOT(alignRight()));
    connect(ui->actionAlign_Justify, SIGNAL(triggered()), this, SLOT(alignJustify()));
    // connect View menu slots
    connect(ui->actionHide_Window, SIGNAL(triggered()), this, SLOT(hide()));
    connect(ui->actionPrevious_Category, SIGNAL(triggered()), this, SLOT(previousCategory()));
    connect(ui->actionNext_Category, SIGNAL(triggered()), this, SLOT(nextCategory()));
    connect(ui->actionPrevious_Note, SIGNAL(triggered()), this, SLOT(previousNote()));
    connect(ui->actionNext_Note, SIGNAL(triggered()), this, SLOT(nextNote()));
    // connect Help menu slots
    connect(ui->actionAbout_Brainstorm, SIGNAL(triggered()), this, SLOT(aboutBrainstorm()));
    connect(ui->actionAbout_Qt, SIGNAL(triggered()), this, SLOT(aboutQt()));
	// connect application slots
	connect(ui->textNote, SIGNAL(cursorPositionChanged()), this, SLOT(updateMenus()));
	connect(ui->textNote, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(updateMenus()));
    connect(ui->comboFonts, SIGNAL(activated(QString)), this, SLOT(setFont(QString)));
    connect(ui->comboFontSizes, SIGNAL(activated(QString)), this, SLOT(setFontSize(QString)));
    connect(ui->comboColors, SIGNAL(activated(int)), this, SLOT(setFontColor(int)));
	// connect category list slots
	connect(ui->listCategories->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateNoteList(QModelIndex)));
	// connect note list slots
	connect(ui->listNotes->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateNoteText(QModelIndex)));
	// connect text slots
	ui->textNote->installEventFilter((this));
	// connect system tray icon
    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

	// initialize default data
	ui->listCategories->selectionModel()->setCurrentIndex(categoriesModel->index(0, 1), QItemSelectionModel::SelectCurrent);

}