Exemple #1
0
bool CWizDatabase::GetChildLocations(const CWizStdStringArray& arrayAllLocation, \
                                     const QString& strLocation, \
                                     CWizStdStringArray& arrayLocation)
{
    if (strLocation.isEmpty())
        return GetAllRootLocations(arrayAllLocation, arrayLocation);

    std::set<QString> setLocation;

    CWizStdStringArray::const_iterator it;
    for (it = arrayAllLocation.begin(); it != arrayAllLocation.end(); it++) {
        const QString& str = *it;

        if (str.length() > strLocation.length() && str.startsWith(strLocation))
        {
            int index = str.indexOf('/', strLocation.length() + 1);
            if (index > 0)
            {
                QString strChild = str.left(index + 1);
                setLocation.insert(strChild);
            }
        }
    }

    arrayLocation.assign(setLocation.begin(), setLocation.end());

    return true;
}
Exemple #2
0
void CWizLoginDialog::setUsers(const QString& strDefault)
{
    CWizStdStringArray usersFolder;
    ::WizEnumFolders(::WizGetDataStorePath(), usersFolder, 0);

    for(CWizStdStringArray::const_iterator it = usersFolder.begin();
        it != usersFolder.end(); it++)
    {
        QString strPath = *it;
        QString strUserId = ::WizFolderNameByPath(strPath);

        QRegExp mailRex("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b");
        mailRex.setCaseSensitivity(Qt::CaseInsensitive);

        if (!mailRex.exactMatch(strUserId))
            continue;

        if (!QFile::exists(strPath + "data/index.db"))
            continue;

        m_comboUsers->addItem(strUserId);
    }

    // set default user as default login entry.
    int i = m_comboUsers->findText(strDefault);
    if (-1 == i) {
        m_comboUsers->insertItem(0, NULL, strDefault);
        m_comboUsers->setCurrentIndex(0);
    } else {
        m_comboUsers->setCurrentIndex(i);
    }
}
    void updateInformation(CWizDatabase& db, const WIZDOCUMENTDATA& doc)
    {
        // retrieve document info and reset
        WIZDOCUMENTDATA data;
        if (!db.DocumentFromGUID(doc.strGUID, data)) {
            return;
        }

        //title
        if (m_titleEdit->text() != data.strTitle) {
            m_titleEdit->setText(data.strTitle);
        }

        //tags
        CWizStdStringArray arrayTagGUID;
        db.GetDocumentTags(data.strGUID, arrayTagGUID);

        QString strTagText = arrayTagGUID.empty() ? QString() : QString::number(arrayTagGUID.size());
        m_tagsButton->setText(strTagText);

        QString tagsShortcut = ::WizGetShortcut("EditNoteTags", "Alt+2");
        QString strTagsToolTip = QObject::tr("Tags (%1)").arg(tagsShortcut);
        m_tagsButton->setToolTip(strTagsToolTip);
        m_tagsButton->setShortcut(QKeySequence::fromString(tagsShortcut));

        //attachments
        int nAttachmentCount = db.GetDocumentAttachmentCount(data.strGUID);
        CString strAttachmentText = nAttachmentCount ? WizIntToStr(nAttachmentCount) : CString();
        m_attachmentButton->setText(strAttachmentText);
        QString attachmentShortcut = ::WizGetShortcut("EditNoteAttachments", "Alt+3");
        m_attachmentButton->setToolTip(QObject::tr("Attachments (%1)").arg(attachmentShortcut));
        m_attachmentButton->setShortcut(QKeySequence::fromString(attachmentShortcut));
    }
Exemple #4
0
void CWizKbSync::queryAttachmentInfo(const CString& strGUID, const CString& strName)
{
    Q_EMIT processLog(tr("query attachment info: ") + strName);

    CWizStdStringArray arrayGUID;
    arrayGUID.push_back(strGUID);
    callAttachmentsGetInfo(arrayGUID);
}
Exemple #5
0
void CWizKbSync::queryDocumentInfo(const CString& strGUID, const CString& strTitle)
{
    Q_EMIT processLog(tr("query note info: ") + strTitle);

    CWizStdStringArray arrayGUID;
    arrayGUID.push_back(strGUID);
    callDocumentsGetInfo(arrayGUID);
}
Exemple #6
0
bool CWizIndexBase::SQLToDocumentDataArray(const CString& strSQL, CWizDocumentDataArray& arrayDocument)
{
    try
    {
        CppSQLite3Query query = m_db.execQuery(strSQL);
        CWizStdStringArray arrayGUID;
        std::map<CString, int> mapDocumentIndex;
        while (!query.eof())
        {
            WIZDOCUMENTDATA data;
            data.strKbGUID = kbGUID();
            data.strGUID = query.getStringField(documentDOCUMENT_GUID);
            data.strTitle = query.getStringField(documentDOCUMENT_TITLE);
            data.strLocation = query.getStringField(documentDOCUMENT_LOCATION);
            data.strName = query.getStringField(documentDOCUMENT_NAME);
            data.strSEO = query.getStringField(documentDOCUMENT_SEO);
            data.strURL = query.getStringField(documentDOCUMENT_URL);
            data.strAuthor = query.getStringField(documentDOCUMENT_AUTHOR);
            data.strKeywords = query.getStringField(documentDOCUMENT_KEYWORDS);
            data.strType = query.getStringField(documentDOCUMENT_TYPE);
            data.strOwner = query.getStringField(documentDOCUMENT_OWNER);
            data.strFileType = query.getStringField(documentDOCUMENT_FILE_TYPE);
            data.strStyleGUID = query.getStringField(documentSTYLE_GUID);
            data.tCreated = query.getTimeField(documentDT_CREATED);
            data.tModified = query.getTimeField(documentDT_MODIFIED);
            data.tAccessed = query.getTimeField(documentDT_ACCESSED);
            data.nIconIndex = query.getIntField(documentDOCUMENT_ICON_INDEX);
            data.nSync = query.getIntField(documentDOCUMENT_SYNC);
            data.nProtected = query.getIntField(documentDOCUMENT_PROTECT);
            data.nReadCount = query.getIntField(documentDOCUMENT_READ_COUNT);
            data.nAttachmentCount = query.getIntField(documentDOCUMENT_ATTACHEMENT_COUNT);
            data.nIndexed = query.getIntField(documentDOCUMENT_INDEXED);
            data.tInfoModified = query.getTimeField(documentDT_INFO_MODIFIED);
            data.strInfoMD5 = query.getStringField(documentDOCUMENT_INFO_MD5);
            data.tDataModified = query.getTimeField(documentDT_DATA_MODIFIED);
            data.strDataMD5 = query.getStringField(documentDOCUMENT_DATA_MD5);
            data.tParamModified = query.getTimeField(documentDT_PARAM_MODIFIED);
            data.strParamMD5 = query.getStringField(documentDOCUMENT_PARAM_MD5);
            data.nVersion = query.getInt64Field(documentVersion);

            arrayGUID.push_back(data.strGUID);
            arrayDocument.push_back(data);
            mapDocumentIndex[data.strGUID] = int(arrayDocument.size() - 1);
            query.nextRow();
        }

        if (!arrayGUID.empty()) {
            InitDocumentExFields(arrayDocument, arrayGUID, mapDocumentIndex);
        }

        return true;
    }
    catch (const CppSQLite3Exception& e)
    {
        return LogSQLException(e, strSQL);
    }
}
Exemple #7
0
bool WizXmlRpcArrayValue::setStringArray(const CWizStdStringArray& arrayData)
{
    CWizStdStringArray::const_iterator it;
    for (it = arrayData.begin(); it != arrayData.end(); it++)
	{
		add(new WizXmlRpcStringValue(*it));
    }

    return true;
}
Exemple #8
0
BOOL CWizXmlRpcArrayValue::SetStringArray(const CWizStdStringArray& arrayData)
{
	for (CWizStdStringArray::const_iterator it = arrayData.begin();
		it != arrayData.end();
		it++)
	{
		Add(new CWizXmlRpcStringValue(*it));
    }

	return TRUE;
}
void CWizFolderView::initFolders()
{
    CWizCategoryViewAllFoldersItem* pAllFoldersItem = new CWizCategoryViewAllFoldersItem(m_app, tr("Note Folders"), m_dbMgr.db().kbGUID());
    addTopLevelItem(pAllFoldersItem);

    CWizStdStringArray arrayAllLocation;
    m_dbMgr.db().GetAllLocations(arrayAllLocation);

    // folder cache
    CWizStdStringArray arrayExtLocation;
    m_dbMgr.db().GetExtraFolder(arrayExtLocation);

    if (!arrayExtLocation.empty()) {
        for (CWizStdStringArray::const_iterator it = arrayExtLocation.begin();
             it != arrayExtLocation.end();
             it++) {
            if (-1 == ::WizFindInArray(arrayAllLocation, *it)) {
                arrayAllLocation.push_back(*it);
            }
        }
    }

    if (arrayAllLocation.empty()) {
        arrayAllLocation.push_back(m_dbMgr.db().GetDefaultNoteLocation());
    }

    initFolders(pAllFoldersItem, "", arrayAllLocation);

    pAllFoldersItem->setExpanded(true);
    pAllFoldersItem->sortChildren(0, Qt::AscendingOrder);
}
Exemple #10
0
bool CWizDatabase::GetAllRootLocations(const CWizStdStringArray& arrayAllLocation, \
                                       CWizStdStringArray& arrayLocation)
{
    std::set<QString> setRoot;

    CWizStdStringArray::const_iterator it;
    for (it = arrayAllLocation.begin(); it != arrayAllLocation.end(); it++) {
        setRoot.insert(GetRootLocation(*it));
    }

    arrayLocation.assign(setRoot.begin(), setRoot.end());

    return true;
}
Exemple #11
0
void CWizSettings::GetKeys(const QString& strSection, CWizStdStringArray& arrayAction)
{
    beginGroup(strSection);
    QStringList sl = childKeys();
    endGroup();
    arrayAction.assign(sl.begin(), sl.end());
}
QString note2Mime(const CWizDocumentDataArray& arrayDocument)
{
    CWizStdStringArray arrayGUID;

    for (CWizDocumentDataArray::const_iterator it = arrayDocument.begin();
         it != arrayDocument.end();
         it++)
    {
        const WIZDOCUMENTDATA& data = *it;
        arrayGUID.push_back(data.strKbGUID + ":" + data.strGUID);
    }

    CString strMime;
    ::WizStringArrayToText(arrayGUID, strMime, ";");

    return strMime;
}
bool WizHtml2Zip(const QString& strHtml, const CWizStdStringArray& arrayResource, \
                 const QString& strMetaText, const QString& strZipFileName)
{
    CWizZipFile zip;
    if (!zip.open(strZipFileName))
        return false;

    QString strHtmlText = strHtml;
    if (strHtmlText.left(2) != " <!")
    {
        strHtmlText = "<!DOCTYPE html>" + strHtmlText;
    }
    CString strIndexFileName = Utils::PathResolve::tempPath() + WizIntToStr(GetTickCount()) + ".html";
    //if (!::WizSaveUnicodeTextToUnicodeFile(strIndexFileName, strHtml))
    if (!::WizSaveUnicodeTextToUtf8File(strIndexFileName, strHtmlText))
        return false;

    CString strMetaFileName = Utils::PathResolve::tempPath() + WizIntToStr(GetTickCount()) + ".xml";
    if (!::WizSaveUnicodeTextToUtf8File(strMetaFileName, strMetaText))
        return false;

    if (!zip.compressFile(strIndexFileName, "index.html"))
        return false;

    int failed = 0;

    if (!zip.compressFile(strMetaFileName, "meta.xml"))
        failed++;

    for (CWizStdStringArray::const_iterator it = arrayResource.begin();
        it != arrayResource.end();
        it++)
    {
        CString strFileName = *it;
        CString strNameInZip = "index_files/" + Utils::Misc::extractFileName(strFileName);
        if (!zip.compressFile(strFileName, strNameInZip))
        {
            failed++;
        }
    }

    return zip.close();
}
void CWizFolderView::initFolders(QTreeWidgetItem* pParent,
                                 const QString& strParentLocation,
                                 const CWizStdStringArray& arrayAllLocation)
{
    CWizStdStringArray arrayLocation;
    CWizDatabase::GetChildLocations(arrayAllLocation, strParentLocation, arrayLocation);

    CWizStdStringArray::const_iterator it;
    for (it = arrayLocation.begin(); it != arrayLocation.end(); it++) {
        QString strLocation = *it;

        if (m_dbMgr.db().IsInDeletedItems(strLocation))
            continue;

        CWizCategoryViewFolderItem* pFolderItem = new CWizCategoryViewFolderItem(m_app, strLocation, m_dbMgr.db().kbGUID());
        pParent->addChild(pFolderItem);

        initFolders(pFolderItem, strLocation, arrayAllLocation);
    }
}
void WelcomeDialog::getUserPasswordPairs()
{
    CWizStdStringArray usersFolder;
    ::WizEnumFolders(::WizGetDataStorePath(), usersFolder, 0);

    for(CWizStdStringArray::const_iterator iter = usersFolder.begin();
        iter != usersFolder.end();
        iter++)
    {
        QString strPath = *iter;
        QString strUserId = ::WizFolderNameByPath(strPath);

        if (strUserId.indexOf("@") == -1) {
            continue;
        }

        CWizUserSettings userSettings(strUserId);
        m_users.insert(strUserId, userSettings.password());
    }
}
Exemple #16
0
BOOL WIZDOCUMENTDATAEX::ParamArrayToStringArray(CWizStdStringArray& params) const
{
    for (std::deque<WIZDOCUMENTPARAMDATA>::const_iterator it = arrayParam.begin();
    it != arrayParam.end();
    it++)
    {
        params.push_back(it->strName + _T("=") + it->strValue);
    }

    return TRUE;
}
Exemple #17
0
BOOL CWizKMDatabaseServer::document_downloadFullListEx(const CWizStdStringArray& arrayDocumentGUID, std::deque<WIZDOCUMENTDATAEX>& arrayRet)
{
    int nCountPerPage = 30;
    //
    CWizStdStringArray::const_iterator it = arrayDocumentGUID.begin();
    //
    while (1)
    {
        //
        CWizStdStringArray subArray;
        //
        for (;
            it != arrayDocumentGUID.end(); )
        {
            subArray.push_back(*it);
            it++;
            //
            if (subArray.size() == nCountPerPage)
                break;
        }
        //
        std::deque<WIZDOCUMENTDATAEX> subRet;
        if (!document_downloadFullList(subArray, subRet))
            return FALSE;
        //
        arrayRet.insert(arrayRet.end(), subRet.begin(), subRet.end());
        //
        if (it == arrayDocumentGUID.end())
            break;
    }
    //
    return TRUE;
}
QWebEngineProfile* createWebEngineProfile(const WizWebEngineViewInjectObjects& objects, QObject* parent)
{
    if (objects.empty())
        return nullptr;
    //
    QWebEngineProfile *profile = new QWebEngineProfile("WizNoteWebEngineProfile", parent);
    //
    QString jsWebChannelFileName = Utils::WizPathResolve::resourcesPath() + "files/webengine/wizwebchannel.js";
    QString jsWebChannel;
    WizLoadUnicodeTextFromFile(jsWebChannelFileName, jsWebChannel);
    //
    QString initFileName = Utils::WizPathResolve::resourcesPath() + "files/webengine/wizwebengineviewinit.js";
    QString jsInit;
    WizLoadUnicodeTextFromFile(initFileName, jsInit);
    //
    CWizStdStringArray names;
    for (auto inject : objects) {
        names.push_back("\"" + inject.name + "\"");
    }
    //
    CString objectNames;
    WizStringArrayToText(names, objectNames, ", ");
    //
    jsInit.replace("__objectNames__", objectNames);
    //
    QString jsAll = jsWebChannel + "\n" + jsInit;
    //
    {
        QWebEngineScript script;
        script.setSourceCode(jsAll);
        script.setName("qwebchannel.js");
        script.setWorldId(QWebEngineScript::MainWorld);
        script.setInjectionPoint(QWebEngineScript::DocumentCreation);
        script.setRunsOnSubFrames(true);
        profile->scripts()->insert(script);
    }
    //
    return profile;
}
Exemple #19
0
void CWizDocumentListView::startDrag(Qt::DropActions supportedActions)
{
    Q_UNUSED(supportedActions);

    CWizStdStringArray arrayGUID;

    QList<QListWidgetItem*> items = selectedItems();
    foreach (QListWidgetItem* it, items) {
        if (CWizDocumentListViewItem* item = dynamic_cast<CWizDocumentListViewItem*>(it)) {
            // not support drag group document currently
            if (item->document().strKbGUID != m_dbMgr.db().kbGUID())
                return;

            arrayGUID.push_back((item->document().strGUID));
        }
    }

    if (arrayGUID.empty())
        return;

    CString strGUIDs;
    ::WizStringArrayToText(arrayGUID, strGUIDs, ";");

    QDrag* drag = new QDrag(this);

    QMimeData* mimeData = new QMimeData();
    mimeData->setData(WIZNOTE_MIMEFORMAT_DOCUMENTS, strGUIDs.toUtf8());
    drag->setMimeData(mimeData);

    // FIXME: need deal with more then 1 drag event!
    if (items.size() == 1) {
        QRect rect = visualItemRect(items[0]);
        drag->setPixmap(QPixmap::grabWindow(winId(), rect.x(), rect.y(), rect.width(), rect.height()));
    }

    drag->exec();
}
bool CWizHtmlCollector::Html2Zip(const QString& strExtResourcePath, \
                                 const QString& strMetaText, \
                                 const QString& strZipFileName)
{
    //CString strMainHtml(strHtml);
    //if (!Collect(strUrl, strMainHtml, true))
    //    return false;

    std::deque<WIZHTMLFILEDATA> arrayResource;
    m_files.GetAll(arrayResource);

    std::set<QString> files;
    std::deque<WIZHTMLFILEDATA>::const_iterator it;
    for (it = arrayResource.begin(); it != arrayResource.end(); it++) {
        files.insert(it->strFileName);
    }

    CWizStdStringArray arrayExtResource;
    if (!strExtResourcePath.isEmpty())
    {
        ::WizEnumFiles(strExtResourcePath, "*.*", arrayExtResource, 0);
        for (CWizStdStringArray::const_iterator it = arrayExtResource.begin();
            it != arrayExtResource.end();
            it++)
        {
            files.insert(*it);
        }
    }

    CString strRet;
    ::WizStringArrayToText(m_ret, strRet, "");

    CWizStdStringArray arrayAllResource;
    arrayAllResource.assign(files.begin(), files.end());

    return WizHtml2Zip(strRet, arrayAllResource, strMetaText, strZipFileName);
}
Exemple #21
0
void CWizSync::queryDocumentInfo(const CString& strGUID, const CString& strTitle)
{
    // if current modified document already inside need download list, means confilict found!
    // no need to query document info anymore.
    std::deque<WIZDOCUMENTDATABASE>::const_iterator it;
    for (it = m_arrayAllDocumentsNeedToBeDownloaded.begin(); \
            it != m_arrayAllDocumentsNeedToBeDownloaded.end();
            it++) {
        WIZDOCUMENTDATABASE data = *it;

        if (data.strGUID == strGUID) {
            Q_EMIT processLog(tr("Conflict found: ") + strTitle);
            m_conflictedDocument = data;
            callDocumentGetData(data);
            return;
        }
    }

    Q_EMIT processLog(tr("query note info: ") + strTitle);

    CWizStdStringArray arrayGUID;
    arrayGUID.push_back(strGUID);
    callDocumentsGetInfo(arrayGUID);
}
Exemple #22
0
bool WizXmlRpcArrayValue::toStringArray(CWizStdStringArray& arrayRet)
{
    std::deque<WizXmlRpcValue*>::const_iterator it;
    for (it = m_array.begin(); it != m_array.end(); it++)
	{
		WizXmlRpcStringValue* pValue = dynamic_cast<WizXmlRpcStringValue*>(*it);
		if (!pValue)
		{
            TOLOG("Fault error: element of array is null or not a string");
            return false;
		}

        QString str = *pValue;
        arrayRet.push_back(str);
	}

    return true;
}
Exemple #23
0
BOOL CWizXmlRpcArrayValue::ToStringArray(CWizStdStringArray& arrayRet)
{
    for (std::deque<CWizXmlRpcValue*>::const_iterator it = m_array.begin();
		it != m_array.end();
		it++)
	{
		CWizXmlRpcStringValue* pValue = dynamic_cast<CWizXmlRpcStringValue*>(*it);
		if (!pValue)
		{
			TOLOG(_T("Fault error: element of array is null or not a string"));
			return FALSE;
		}
		//
		arrayRet.push_back(pValue->ToString());
	}
	//
	return TRUE;
}
Exemple #24
0
bool CWizIndexBase::SQLToStringArray(const CString& strSQL, int nFieldIndex, CWizStdStringArray& arrayString)
{
    try
    {
        CppSQLite3Query query = m_db.execQuery(strSQL);
        while (!query.eof())
        {
            CString strGUID = query.getStringField(nFieldIndex);

            arrayString.push_back(strGUID);
            query.nextRow();
        }
        return true;
    }
    catch (const CppSQLite3Exception& e)
    {
        return LogSQLException(e, strSQL);
    }
}
Exemple #25
0
GenericName[en_US.UTF-8]=WizNote\n\
";


void installOnLinux()
{
    QString appPath = Utils::PathResolve::appPath();
    QString strText = WizFormatString3(g_lpszDesktopFileName,
                                       appPath,
                                       QObject::tr("WizNote"),
                                       QObject::tr("WizNote"));
    //
    QString applicationsPath = QDir::homePath() + "/.local/share/applications/";
    ::WizEnsurePathExists(applicationsPath);
    //
    QString iconsBasePath = QDir::homePath() + "/.local/share/icons/hicolor/";
    ::WizEnsurePathExists(applicationsPath);
    //
    CWizStdStringArray arrayIconSize;
    arrayIconSize.push_back("16");
    arrayIconSize.push_back("32");
    arrayIconSize.push_back("48");
    arrayIconSize.push_back("64");
    arrayIconSize.push_back("128");
    arrayIconSize.push_back("256");
    for (CWizStdStringArray::const_iterator it = arrayIconSize.begin();
            it != arrayIconSize.end();
            it++)
    {
        QString iconSize = *it;
        QString iconPathName = iconSize + "x" + iconSize;
        QString iconFullPath = iconsBasePath + iconPathName + "/apps/";
        WizEnsurePathExists(iconFullPath);
        //
        QString resourceName = ":/logo_" + iconSize + ".png";
        QPixmap pixmap(resourceName);
        if (pixmap.isNull())
            continue;
        //
        pixmap.save(iconFullPath + "wiznote.png");
    }

    QString desktopFileName = applicationsPath + "wiznote.desktop";
    ::WizSaveUnicodeTextToUtf8File(desktopFileName, strText, false);
    //
    chmod(desktopFileName.toUtf8(), ACCESSPERMS);
}
void CWizFolderView::initFolders()
{
    CWizCategoryViewAllFoldersItem* pAllFoldersItem = new CWizCategoryViewAllFoldersItem(m_app, tr("Note Folders"), m_dbMgr.db().kbGUID());
    addTopLevelItem(pAllFoldersItem);

    CWizStdStringArray arrayAllLocation;
    m_dbMgr.db().GetAllLocations(arrayAllLocation);

    initFolders(pAllFoldersItem, "", arrayAllLocation);

    if (arrayAllLocation.empty()) {
        const QString strNotes("/My Notes/");
        m_dbMgr.db().AddExtraFolder(strNotes);
        m_dbMgr.db().SetObjectVersion("folder", 0);
        arrayAllLocation.push_back(strNotes);
    }

    //init extra folders
    CWizStdStringArray arrayExtLocation;
    m_dbMgr.db().GetExtraFolder(arrayExtLocation);

    CWizStdStringArray::const_iterator it;
    for (it = arrayExtLocation.begin(); it != arrayExtLocation.end(); it++) {
        QString strLocation = *it;

        if (strLocation.isEmpty())
            continue;

        if (m_dbMgr.db().IsInDeletedItems(strLocation))
            continue;

        addFolder(strLocation, true);
    }

    pAllFoldersItem->setExpanded(true);
    pAllFoldersItem->sortChildren(0, Qt::AscendingOrder);
}
Exemple #27
0
void CWizSettings::GetSections(CWizStdStringArray& arrayAction)
{
    QStringList sl = childGroups();
    arrayAction.assign(sl.begin(), sl.end());
}
bool WizKMCombineDocumentsToHtmlFile(WizDatabaseManager& dbMgr, const CWizDocumentDataArray& arrayDocument, QString splitter, bool addTitle, QString& strResultFileName, CWizDocumentAttachmentDataArray& arrayAttachment, QString& strError)
{
    QString strTempPath = Utils::WizPathResolve::tempPath() + WizGenGUIDLowerCaseLetterOnly() + "/";
    ::WizEnsurePathExists(strTempPath);
    //
    CWizStdStringArray htmls;
    //
    size_t nCount = arrayDocument.size();
    for (size_t i = 0; i < nCount; i++)
    {
        WIZDOCUMENTDATA doc = arrayDocument[i];
        //
        WizDatabase& db = dbMgr.db(doc.strKbGUID);
        if (!db.isDocumentDownloaded(doc.strGUID))
        {
            strError = QObject::tr("Note has not been downloaded");
            return false;
        }
        //
        if (!db.documentToHtmlFile(doc, strTempPath))
        {
            strError = QObject::tr("Failed to get note data");
            return false;
        }
        //
        QString htmlFileName = strTempPath + "index.html";
        if (!QFileInfo::exists(htmlFileName))
        {
            strError = QObject::tr("Failed to get note data");
            return false;
        }
        //
        QString html;
        if (!WizLoadUnicodeTextFromFile(htmlFileName, html))
        {
            strError = QObject::tr("Failed to read note data");
            return false;
        }
        //
        htmls.push_back(html);
        //
        CWizDocumentAttachmentDataArray atts;
        db.getDocumentAttachments(doc.strGUID, atts);
        for (WIZDOCUMENTATTACHMENTDATA att : atts)
        {
            if (!db.isAttachmentDownloaded(att.strGUID))
            {
                strError = QObject::tr("Note attachment %1 has not been downloaded").arg(att.strName);
                return false;
            }
            //
            arrayAttachment.push_back(att);
        }
    }
    //
    CString strAllHTML;
    //
    for (size_t i = 0; i < nCount; i++)
    {
        CString html = htmls[i];
        WIZDOCUMENTDATA doc = arrayDocument[i];
        if (-1 != WizStrStrI_Pos(html, CString(_T("<frameset"))))
        {
            strError = QObject::tr("Cannot combine html because html contains frame set");
            return false;
        }
        //
        CString strTitle = doc.strTitle;
        WizOleDateTime t = doc.tCreated;
        CString strDate = t.toLocalLongDate();
        //
        if (addTitle)
        {
            CString strInfoHtml = WizFormatString2(_T("<h2>%1 (%2)</h2>"), strTitle, strDate);
            ::WizHTMLInsertTextBeforeBody(strInfoHtml, html);
        }
        //
        if (!WizCombineHtmlText(strAllHTML, html))
        {
            strError = QObject::tr("Cannot combine html");
            return false;
        }
        //
        if (i < nCount - 1)
        {
            if (!splitter.isEmpty())
            {
                WizCombineHtmlText(strAllHTML, splitter);
            }
        }
    }
    //
    strResultFileName = strTempPath + "index.html";
    //
    bool ret = ::WizSaveUnicodeTextToUtf8File(strResultFileName, strAllHTML);
    if (!ret)
    {
        strError = QObject::tr("Cannot save note html");
        return false;
    }
    return true;
}