Full Code of GDPURJYFS/WellChat for AI

master a861ddfd961b cached
97 files
248.8 KB
57.0k tokens
26 symbols
1 requests
Download .txt
Showing preview only (278K chars total). Download the full file or copy to clipboard to get everything.
Repository: GDPURJYFS/WellChat
Branch: master
Commit: a861ddfd961b
Files: 97
Total size: 248.8 KB

Directory structure:
gitextract_f1fzdbi7/

├── .gitignore
├── LICENSE
├── README.md
├── Sparrow/
│   ├── Sparrow.pri
│   ├── keyboard.cpp
│   ├── keyboard.h
│   ├── qmlnetworkaccessmanagerfactory.cpp
│   ├── qmlnetworkaccessmanagerfactory.h
│   ├── qtbridgingandroid.cpp
│   ├── qtbridgingandroid.h
│   └── sparrow_global.h
├── WellChat.pro
├── android/
│   ├── AndroidManifest.xml
│   ├── assets/
│   │   └── font/
│   │       └── NotoSansHans-DemiLight.otf
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── res/
│   │   └── values/
│   │       └── libs.xml
│   └── src/
│       └── org/
│           └── gdpurjyfs/
│               ├── sparrow/
│               │   └── QtBridgingAndroid.java
│               └── wellchat/
│                   └── WellChatActivity.java
├── deployment.pri
├── desktop.qrc
├── doc/
│   └── weixin-ui-analyse.md
├── main.cpp
├── qml/
│   └── WellChat/
│       ├── BussinessPage/
│       │   ├── Chat/
│       │   │   ├── ChatPage.qml
│       │   │   ├── Heartbeat.qml
│       │   │   ├── Lazy.qml
│       │   │   ├── Tuling123.js
│       │   │   └── heart.js
│       │   ├── ChatsView.qml
│       │   ├── Contacts/
│       │   │   └── ContactsListView.qml
│       │   ├── ContactsView.qml
│       │   ├── Discover/
│       │   │   └── MomentsPage/
│       │   │       └── MomentsPage.qml
│       │   ├── DiscoverPage.qml
│       │   ├── Personal/
│       │   │   ├── FavoritesPage.qml
│       │   │   ├── MyPostsPage.qml
│       │   │   ├── Settings/
│       │   │   │   ├── AboutPage.qml
│       │   │   │   ├── ChatSettingsPage.qml
│       │   │   │   ├── DoNotDisturbSettingsPage.qml
│       │   │   │   ├── GeneralSettingsPage.qml
│       │   │   │   ├── MyAccountSettingsPage.qml
│       │   │   │   ├── NotificationsSettingsPage.qml
│       │   │   │   ├── PrivacySettingsPage.qml
│       │   │   │   └── SettingsGroup.qml
│       │   │   └── SettingsPage.qml
│       │   ├── PersonalPage.qml
│       │   ├── ProfilePage.qml
│       │   ├── R.qml
│       │   └── qmldir
│       ├── Component/
│       │   ├── +android/
│       │   │   └── UI.js
│       │   ├── Constant.qml
│       │   ├── Icon.qml
│       │   ├── IconButton.qml
│       │   ├── IconLabel.qml
│       │   ├── MainListView.qml
│       │   ├── SampleTextArea.qml
│       │   ├── ScrollBar.qml
│       │   ├── Separator.qml
│       │   └── UI.js
│       ├── MainView.qml
│       ├── Sparrow/
│       │   ├── +android/
│       │   │   ├── UI.js
│       │   │   └── WebPage.qml
│       │   ├── BottomBar.qml
│       │   ├── ClickedShaderEffect.qml
│       │   ├── GeneralSettings.qml
│       │   ├── Page.qml
│       │   ├── PageStackWindow.qml
│       │   ├── PopupLayer/
│       │   │   ├── Delegate/
│       │   │   │   ├── PopupLayerBottomMenuDelegate.qml
│       │   │   │   ├── PopupLayerDialogDelegate.qml
│       │   │   │   ├── PopupLayerSideMenuDelegate.qml
│       │   │   │   └── qmldir
│       │   │   ├── PopupLayer.qml
│       │   │   ├── PopupLayerDelegate.qml
│       │   │   ├── PopupLayerTransition.qml
│       │   │   ├── qmldir
│       │   │   └── readme.md
│       │   ├── QObject.qml
│       │   ├── SampleButton.qml
│       │   ├── SampleIcon.qml
│       │   ├── SampleLabel.qml
│       │   ├── SampleTextField.qml
│       │   ├── TopBar.qml
│       │   ├── Tracker.qml
│       │   ├── UI.js
│       │   ├── WebPage.qml
│       │   ├── qmldir
│       │   └── resources/
│       │       ├── NotoSansHans-DemiLight.otf
│       │       └── readme.md
│       ├── WellChat.qmlproject
│       ├── main.qml
│       └── resource/
│           ├── R.qml
│           └── qmldir
├── qml.qrc
└── src/
    └── wellchat/
        ├── collectionsmodel.cpp
        └── collectionsmodel.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
WellChat.pro.user
*.user

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 GDPURJYFS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
# WellChat

WellChat is a Application that is a WeChat-like APP by qml.

> best tool vesion:

> Qt version >= 5.5.0

> Android SDK APi >= 19

> Android 5.0 or new

使用 qml 来仿制安卓微信的 Qt 程序,可以运行在安卓上。

## 界面展示

### 480 * 800

微信界面

![](Screenshot/480x800/WeChat.png)

仿制界面

![](Screenshot/480x800/WellChat-01.png)

![](Screenshot/480x800/WellChat-02.png)

![](Screenshot/480x800/WellChat-03.png)

![](Screenshot/480x800/WellChat-04.png)

### 1080P

微信界面

![](Screenshot/1080x1920/WellChat01.jpg)

![](Screenshot/1080x1920/WellChat02.jpg)

![](Screenshot/1080x1920/WellChat03.jpg)

![](Screenshot/1080x1920/WellChat04.jpg)  

![](Screenshot/1080x1920/WellChat05.jpg)  

![](Screenshot/1080x1920/WellChat06.jpg)

![](Screenshot/1080x1920/WellChat07.jpg)

![](Screenshot/1080x1920/WellChat08.jpg)

植入图灵聊天机器人的聊天界面

![](Screenshot/1080x1920/WellChat09.jpg)

## QML开发安卓应用的局限

`QtQuick.Control` 这个模块是专门为桌面平台准备的,对移动平台支持并不完善。不能很好地动态切换不同的 `ToolBar` 和 `StatusBar` 来适配不同的页面。

如何设计一个简单的页面栈呢?查看[简单易用的页面栈框架](https://github.com/GDPURJYFS/Sparrow)

## 剖析界面

微信界面的主要操作交互逻辑有首界面的四个可以切换的分页,以及一个页面栈。查看[微信界面剖析](doc/weixin-ui-analyse.md)

---

***images and protocol Copyright (C) by [Tencent] (http://weixin.qq.com/)*** 

***图片、协议版权归[腾讯] (http://weixin.qq.com/) 所有!***

================================================
FILE: Sparrow/Sparrow.pri
================================================
QT += core network sql qml

android {
    QT += androidextras

}

HEADERS += \
    #$$PWD/qmlnetworkaccessmanagerfactory.h \
    #$$PWD/notificationclient.h \
    $$PWD/keyboard.h \
    $$PWD/sparrow_global.h \
    #$$PWD/qtnativeforandroid.h \
    $$PWD/qtbridgingandroid.h

SOURCES += \
    #$$PWD/qmlnetworkaccessmanagerfactory.cpp \
    #$$PWD/notificationclient.cpp \
    $$PWD/keyboard.cpp \
    #$$PWD/qtnativeforandroid.cpp \
    $$PWD/qtbridgingandroid.cpp

OTHER_FILES += $$PWD/../android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
# $$PWD/../android/src/org/gdpurjyfs/sparrow/QtNativeForAndroid.java \

DISTFILES +=




================================================
FILE: Sparrow/keyboard.cpp
================================================
#include "keyboard.h"
#include <QGuiApplication>
#include <QInputMethod>

#include "sparrow_global.h"

Keyboard::Keyboard(QObject *parent) :
    QObject(parent),
    m_inputMethod (QGuiApplication::inputMethod())
{
    connect(m_inputMethod, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()));

#ifndef Q_OS_ANDROID
    connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChangedChanged()));
#endif

}

bool Keyboard::visible() const
{
    return m_inputMethod->isVisible();
}

void Keyboard::setVisible(bool v)
{
    if(v) {
        m_inputMethod->show();
    } else {
        m_inputMethod->hide();
    }
}

QRectF Keyboard::keyboardRectangle() const
{
    return this->m_keyboardRectangle;
}

Keyboard *Keyboard::singleton()
{
    static Keyboard* keyboard = new Keyboard(QCoreApplication::instance());
    return keyboard;
}

void Keyboard::setKeyboardRectangle(const QRectF &keyboardRectangle)
{
    if(this->keyboardRectangle() != keyboardRectangle) {
        this->m_keyboardRectangle = keyboardRectangle;
        emit keyboardRectangleChanged(this->m_keyboardRectangle);
    }
}

void Keyboard::onVisibleChangedChanged()
{
#ifndef Q_OS_ANDROID
    this->setKeyboardRectangle(m_inputMethod->keyboardRectangle());
#endif
}




================================================
FILE: Sparrow/keyboard.h
================================================
#ifndef VIRTUALKEYBOARD_H
#define VIRTUALKEYBOARD_H

#include <QObject>
#include <QRectF>

class QtBridgingAndroid;
class QtNativeForAndroid;
class QInputMethod;

class Keyboard : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
    Q_PROPERTY(QRectF keyboardRectangle READ keyboardRectangle NOTIFY keyboardRectangleChanged)

public:
    explicit Keyboard(QObject *parent = 0);

    bool visible()const;
    void setVisible(bool v);

    QRectF keyboardRectangle()const;

    static Keyboard *singleton();

signals:
    void visibleChanged();
    void keyboardRectangleChanged(const QRectF& keyboardRectangle);

protected slots:
    void setKeyboardRectangle(const QRectF& keyboardRectangle);

private slots:
    void onVisibleChangedChanged();

private:
    QInputMethod* m_inputMethod;
    QRectF m_keyboardRectangle;
    friend class QtNativeForAndroid;
    friend class QtBridgingAndroid;
};

#endif // VIRTUALKEYBOARD_H


================================================
FILE: Sparrow/qmlnetworkaccessmanagerfactory.cpp
================================================
#include "qmlnetworkaccessmanagerfactory.h"

#include <QDir>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QStandardPaths>

QmlNetworkAccessManagerFactory::QmlNetworkAccessManagerFactory()
{
#ifdef QT_DEBUG
    qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
#endif
}

QmlNetworkAccessManagerFactory::~QmlNetworkAccessManagerFactory()
{
#ifdef QT_DEBUG
    qDebug() << "~QmlNetworkAccessManagerFactory";
#endif
}

QNetworkAccessManager *QmlNetworkAccessManagerFactory::create(QObject *parent)
{
    QNetworkAccessManager* manager = new QNetworkAccessManager(parent);
    QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);

    if(QDir().mkpath(cachePath)) {
        QNetworkDiskCache* diskCache = new QNetworkDiskCache(manager);
        diskCache->setCacheDirectory(cachePath);
        diskCache->setMaximumCacheSize(10*1024*1024);
        manager->setCache(diskCache);
    }

    return manager;
}



================================================
FILE: Sparrow/qmlnetworkaccessmanagerfactory.h
================================================
#ifndef QMLNETWORKACCESSMANAGERFACTORY_H
#define QMLNETWORKACCESSMANAGERFACTORY_H

#include <QQmlNetworkAccessManagerFactory>

class QmlNetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
{
public:
    QmlNetworkAccessManagerFactory();
    ~QmlNetworkAccessManagerFactory();
    QNetworkAccessManager *create(QObject *parent);
};

#endif // QMLNETWORKACCESSMANAGERFACTORY_H


================================================
FILE: Sparrow/qtbridgingandroid.cpp
================================================
#include "qtbridgingandroid.h"
#include "keyboard.h"
#include <QRect>
#include <QRectF>
#include <QGuiApplication>

QtBridgingAndroid::QtBridgingAndroid(QObject *parent)
    : QObject(parent)
{

}

void QtBridgingAndroid::sendNotification(const QString &notifyString)
{

#ifdef Q_OS_ANDROID

#ifdef QT_DEBUG
    qDebug() << "sending... ";
#endif

    QAndroidJniObject javaNotification = QAndroidJniObject::fromString(notifyString);
    // org/gdpurjyfs/wellchat/NotificationClient
    // org/gdpurjyfs/wellchat/QtBridgingAndroid
    // org/gdpurjyfs/sparrow/QtBridgingAndroid
    QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
                                              "notify",
                                              "(Ljava/lang/String;)V",
                                              javaNotification.object<jstring>()
                                              );
    Q_SAFE_CALL_JAVA

#endif

#ifndef Q_OS_ANDROID
    Q_UNUSED(notifyString)
    qDebug() << "not allow to use the QtAndroidExtras";
#endif
}

void QtBridgingAndroid::setStatusBarColor(const QColor &color)
{

#ifdef Q_OS_ANDROID
    QString colorString = color.name(QColor::HexRgb);
    QAndroidJniObject javaColorString = QAndroidJniObject::fromString(colorString);

#ifdef QT_DEBUG
    qDebug() << "colorString" << colorString;
#endif

    // org/gdpurjyfs/wellchat/QtBridgingAndroid
    // org/gdpurjyfs/sparrow/QtBridgingAndroid
    QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
                                              "setStatusBarColor",
                                              "(Ljava/lang/String;)V",
                                              javaColorString.object<jstring>()
                                              );
    Q_SAFE_CALL_JAVA

#else
    Q_UNUSED(color)
#endif

#ifndef Q_OS_ANDROID
    qDebug() << "not allow to use the QtAndroidExtras";
#endif

}

#ifdef Q_OS_ANDROID

// 在 Java 中被调用
void QtBridgingAndroid::notifiedKeyboardRectangle(JNIEnv *env, jobject thiz,
                                                  jint x, jint y, jint width, jint height)
{
    Q_UNUSED(env)
    Q_UNUSED(thiz)

    if(QGuiApplication::applicationState() != Qt::ApplicationHidden) {

#ifdef QT_DEBUG
        qDebug() << "invoke method notifiedKeyboardRectangle: " <<
#endif
        QMetaObject::invokeMethod(Keyboard::singleton(),
                                  "setKeyboardRectangle",
                                  Qt::AutoConnection,
                                  Q_ARG(QRectF, QRect(x, y, width, height))) ;

    }
}

bool QtBridgingAndroid::registerNativeMethodForJava()
{
    JNINativeMethod methods[] = {
        {
            "notifiedKeyboardRectangle",
            "(IIII)V",
            (void*)&(QtBridgingAndroid::notifiedKeyboardRectangle)
        }
    };

    // org/gdpurjyfs/wellchat/QtBridgingAndroid

    // "org/gdpurjyfs/sparrow/qtnativeforandroid" // 包名
    // const char * classname = "org/gdpurjyfs/sparrow/QtNativeForAndroid";
    const char * classname = "org/gdpurjyfs/sparrow/QtBridgingAndroid";
    jclass clazz;
    QAndroidJniEnvironment env;

    QAndroidJniObject javaClass(classname);
    clazz = env->GetObjectClass(javaClass.object<jobject>());

    Q_SAFE_CALL_JAVA

    bool result = false;
    if(clazz) {
        jint ret = env->RegisterNatives(clazz,
                                        methods,
                                        sizeof(methods) / sizeof(methods[0]));
        //! [bug] env->DeleteGlobalRef(clazz);
        result = (ret >= 0);
    } else {
#ifdef QT_DEBUG
        qDebug() << "can't find java class" << classname;
#endif
    }

    Q_SAFE_CALL_JAVA

    return result;
}

void QtBridgingAndroid::installListener()
{
#ifdef Q_OS_ANDROID
    // org/gdpurjyfs/wellchat/NotificationClient
    // org/gdpurjyfs/wellchat/QtBridgingAndroid
    // org/gdpurjyfs/sparrow/QtBridgingAndroid
    QAndroidJniObject::callStaticMethod<void>("org/gdpurjyfs/sparrow/QtBridgingAndroid",
                                              "listenKeyboardHeight");
    Q_SAFE_CALL_JAVA
#endif
}

#endif


================================================
FILE: Sparrow/qtbridgingandroid.h
================================================
#ifndef QTBRIDGINGANDROID_H
#define QTBRIDGINGANDROID_H

#include <QObject>
#include <QColor>
#include "sparrow_global.h"

class QtBridgingAndroid : public QObject
{
    Q_OBJECT
public:
    explicit QtBridgingAndroid(QObject *parent = 0);

    // Java Method
    Q_INVOKABLE void sendNotification(const QString& notifyString);
    // Java Method
    Q_INVOKABLE void setStatusBarColor(const QColor& color);

public:
#ifdef Q_OS_ANDROID
    static void notifiedKeyboardRectangle(JNIEnv * env, jobject thiz,
                         jint x, jint y, jint width, jint height);
    static bool registerNativeMethodForJava();

    static void installListener();

#endif

};

#endif // QTBRIDGINGANDROID_H


================================================
FILE: Sparrow/sparrow_global.h
================================================
#ifndef GLOBAL
#define GLOBAL

#include <QDebug>

#ifdef Q_OS_ANDROID

#include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
#define Q_SAFE_CALL_JAVA {                  \
    QAndroidJniEnvironment env;             \
    if(env->ExceptionCheck()) {             \
    qDebug() << "have a java exception";    \
    env->ExceptionClear();                  \
    }                                       \
    }

#endif

#endif // GLOBAL



================================================
FILE: WellChat.pro
================================================
TEMPLATE = app

QT += qml quick widgets

SOURCES += main.cpp \
    src/wellchat/collectionsmodel.cpp

RESOURCES += \
    qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)
include(Sparrow/Sparrow.pri)

DISTFILES += \
    android/AndroidManifest.xml \
    android/gradle/wrapper/gradle-wrapper.jar \
    android/gradlew \
    android/res/values/libs.xml \
    android/build.gradle \
    android/gradle/wrapper/gradle-wrapper.properties \
    android/gradlew.bat

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

OTHER_FILES += android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
# android/src/org/gdpurjyfs/wellchat/QtBridgingAndroid.java \

HEADERS += \
    src/wellchat/collectionsmodel.h



================================================
FILE: android/AndroidManifest.xml
================================================
<?xml version="1.0"?>
<manifest package="org.gdpurjyfs.wellchat" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.0.1" android:versionCode="1" android:installLocation="auto">
    <application android:icon="@drawable/icon" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name">
        <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.gdpurjyfs.wellchat.WellChatActivity" android:label="WellChat" android:screenOrientation="unspecified" android:windowSoftInputMode="adjustPan">
            <!-- android:windowSoftInputMode = "adjustUnspecified" -->
            <!-- android:windowSoftInputMode = "adjustPan" -->
            <!-- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
            <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
            <meta-data android:name="android.app.repository" android:value="default"/>
            <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
            <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
            <!-- Deploy Qt libs as part of package -->
            <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
            <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
            <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
            <!-- Run with local libs -->
            <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
            <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
            <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
            <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
            <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
            <!--  Messages maps -->
            <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
            <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
            <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
            <!--  Messages maps -->
            <!-- Splash screen -->
            <!--
            <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
            -->
            <!-- Splash screen -->

            <!-- Background running -->
            <!-- Warning: changing this value to true may cause unexpected crashes if the
                          application still try to draw after
                          "applicationStateChanged(Qt::ApplicationSuspended)"
                          signal is sent! -->
            <meta-data android:name="android.app.background_running" android:value="true"/>
            <!--
                qt start: 11:58:35
                qt died:  12:13:58
                这个方法不稳定,因为在QtCreator不能继续跟踪打印。
            -->
            <!-- Background running -->
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
    <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
    <!-- %%INSERT_PERMISSIONS -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- %%INSERT_FEATURES -->
</manifest>


================================================
FILE: android/build.gradle
================================================
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.0'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

apply plugin: 'com.android.application'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

android {
    /*******************************************************
     * The following variables:
     * - androidBuildToolsVersion,
     * - androidCompileSdkVersion
     * - qt5AndroidDir - holds the path to qt android files
     *                   needed to build any Qt application
     *                   on Android.
     *
     * are defined in gradle.properties file. This file is
     * updated by QtCreator and androiddeployqt tools.
     * Changing them manually might break the compilation!
     *******************************************************/

    compileSdkVersion androidCompileSdkVersion.toInteger()

    buildToolsVersion androidBuildToolsVersion

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
            aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
            res.srcDirs = [qt5AndroidDir + '/res', 'res']
            resources.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
       }
    }

    lintOptions {
        abortOnError false
    }
}


================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip


================================================
FILE: android/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: android/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: android/res/values/libs.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<resources>
    <array name="qt_sources">
        <item>https://download.qt-project.org/ministro/android/qt5/qt-5.4</item>
    </array>

    <!-- The following is handled automatically by the deployment tool. It should
         not be edited manually. -->

    <array name="bundled_libs">
        <!-- %%INSERT_EXTRA_LIBS%% -->
    </array>

     <array name="qt_libs">
         <!-- %%INSERT_QT_LIBS%% -->
     </array>

    <array name="bundled_in_lib">
        <!-- %%INSERT_BUNDLED_IN_LIB%% -->
    </array>
    <array name="bundled_in_assets">
        <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
    </array>

</resources>


================================================
FILE: android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
================================================
/*
 * Copyright (c) <2015> <copyright qyvlik>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

/*!
 * Activity 先于 Qt 加载
 * 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main
 * 2. 在 Qt::main 中注册 Java 的 native 函数 QtBridgingAndroid::notifiedKeyboardRectangle
 * 3. 在 Qt::main 通过调用 Java::QtBridgingAndroid::listenKeyboardHeight 注入监听键盘事件
 * 4. 在 Qt::main 加载 QML。
*/

package org.gdpurjyfs.sparrow;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.app.Activity;
import android.os.Bundle;
import android.graphics.Color;
import android.app.Activity;
import android.view.Window;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.view.ViewTreeObserver;
import android.graphics.Rect;
import android.view.ViewGroup;

import java.lang.Thread;

//! http://blog.csdn.net/foruok/article/details/46323129
class SetStatusBarColorRunnable implements Runnable
{
    private Activity m_activity;
    private int m_color;
    public SetStatusBarColorRunnable(Activity activity, int color) {
        m_activity = activity;
        m_color = color;
    }
    // this method is called on Android Ui Thread
    @Override
    public void run() {
        m_activity.getWindow().setStatusBarColor(m_color);
    }
}

public class QtBridgingAndroid
{   
    public static Activity instanceActivity;
    
    private static NotificationManager notificationManager;
    private static Notification.Builder builder;
    private static Rect keyboardRectangle;
    private static boolean hasListenVirtualKeyboard = false;
    
    // allow Qt call this static function
    // api 19
    // @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    // android.view.ViewRootImpl$CalledFromWrongThreadException
    //! http://daydayup1989.iteye.com/blog/784831
    public static void setStatusBarColor(String colorString) {
        if(instanceActivity != null) {
            try {
                System.out.println("colorString: " + colorString);
                int color = Color.parseColor(colorString);
                System.out.println("color: " + color);
                instanceActivity.runOnUiThread(new SetStatusBarColorRunnable(instanceActivity,
                                                                             color));
            } catch(IllegalArgumentException e) {
                e.printStackTrace();
            } catch(Exception e1) {
                e1.printStackTrace();
            }
        }
    }

    // allow Qt call this static function
    public static void notify(String notifyText)
    {
        if (notificationManager == null) {
            notificationManager = (NotificationManager)instanceActivity.getSystemService(Context.NOTIFICATION_SERVICE);
            builder = new Notification.Builder(instanceActivity);
            builder.setSmallIcon(org.gdpurjyfs.wellchat.R.drawable.icon);
            builder.setContentTitle("WellChat");
        }

        System.out.println("set setContentText");
        builder.setContentText(notifyText);
        notificationManager.notify(1, builder.build());
    }
    
    private static View getRootView(Activity context)
    {
        return ((ViewGroup)context.findViewById(android.R.id.content)).getChildAt(0);
    }
    

    // 确保Qt调用时,只注入一次键盘监听事件
    public static void listenKeyboardHeight() {
        if(!hasListenVirtualKeyboard) {
            final View myRootView = getRootView(instanceActivity);
            myRootView.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {

                    Rect outRect = new Rect();
                    instanceActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);

                    keyboardRectangle = new Rect();
                    myRootView.getWindowVisibleDisplayFrame(keyboardRectangle);

                    int screenHeight = myRootView.getRootView().getHeight();
                    // 小于100 就不行了
                    // 这里还要减去状态栏的高度
                    // 魔幻数字
                    // android:windowSoftInputMode="adjustPan" magic = 0
                    // 其他情况为 5
                    int magic = 0;
                    int virtualKeyboardHeight = screenHeight - (keyboardRectangle.bottom - keyboardRectangle.top) 
                                                - outRect.top - magic;

                    if( virtualKeyboardHeight < 100 ) {
                        virtualKeyboardHeight = 0;
                    }

                    // java 通知 Qt 键盘改变了
                    System.out.println("try to call native method");
                    notifiedKeyboardRectangle(
                            keyboardRectangle.centerX(),
                            keyboardRectangle.centerY(),
                            keyboardRectangle.width(),
                            virtualKeyboardHeight);
                }
            });
            hasListenVirtualKeyboard = true;
        }
    }
    
    // allow java call this native method
    public static native void notifiedKeyboardRectangle(int x, int y,
                                                        int width, int height);
    
    // Java call this method and init this static Bridge Class
    public static void Init(Activity instanceActivity) {
        QtBridgingAndroid.instanceActivity = instanceActivity;

        System.out.println("QtBridgingAndroid::Init");
    }
}


================================================
FILE: android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
================================================
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/

package org.gdpurjyfs.wellchat;



import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.app.Activity;
import android.view.Window;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;
import android.view.ViewTreeObserver;
import android.graphics.Rect;
import android.view.ViewGroup;
import android.os.Bundle;

//import org.gdpurjyfs.sparrow;

public class WellChatActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
//    @Override
//    public void onCreate (Bundle savedInstanceState){
//        System.out.println("这里竟然不能有其他复杂的函数操作,会闪退的。");
//        super.onCreate(savedInstanceState);
//        org.gdpurjyfs.sparrow.QtBridgingAndroid.Init(this);
//    }

    public WellChatActivity()
    {
        org.gdpurjyfs.sparrow.QtBridgingAndroid.Init(this);
    }

}


================================================
FILE: deployment.pri
================================================
android-no-sdk {
    target.path = /data/user/qt
    export(target.path)
    INSTALLS += target
} else:android {
    QT += androidextras
    x86 {
        target.path = /libs/x86
    } else: armeabi-v7a {
        target.path = /libs/armeabi-v7a
    } else {
        target.path = /libs/armeabi
    }
    export(target.path)
    INSTALLS += target
} else:unix {
    isEmpty(target.path) {
        qnx {
            target.path = /tmp/$${TARGET}/bin
        } else {
            target.path = /opt/$${TARGET}/bin
        }
        export(target.path)
    }
    INSTALLS += target
}

win32 {
    RESOURCES += \
        desktop.qrc
}

export(INSTALLS)


================================================
FILE: desktop.qrc
================================================
<RCC>
    <qresource prefix="/">
        <file>qml/WellChat/Sparrow/resources/NotoSansHans-DemiLight.otf</file>
    </qresource>
</RCC>


================================================
FILE: doc/weixin-ui-analyse.md
================================================
# 微信界面剖析

微信界面剖析分为:首界面,单个界面,字体大小,素材等。

## 首界面

可以先查看[简单易用的页面栈框架](readme.md)。

先看看微信的首界面。有四个分页,`BottomBar` 可以显示当前页面的以及进行切换。`TopBar` 显示微信的应用名称和两个按钮。所以首页面的实现可以使用一个横向的 `ListView` 来实现,内部有四个不同的页面,使用 `VisualItemModel` 进行加载。

![weixin-ui-analyse-01](images/weixin-ui-analyse-01.png)

现在取其中的聊天界面为例子。

![weixin-ui-analyse-02](images/weixin-ui-analyse-02.png)

在点开一个联系人进行聊天时,会将一个聊天页面压入页面栈。

![weixin-ui-analyse-03](images/weixin-ui-analyse-03.png)

先不管聊天界面是如何实现的。就讲讲页面压栈要注意的问题。

先回到首界面的 `Chats`。里面有若干个联系人,在点击某一个联系人之后,触发一个函数,将聊天页面压入栈。一般是由 `MouseArea` 触发 `clicked` 信号,然后触发页面入栈的函数。

问题来了,由于页面入栈的实现问题,`StackView` 将一个页面推入栈顶是需要时间的,所以 `StackView` 会产生一个过渡,来提高用户体验,如果你的手速够快的话,双击某个联系人,会不会触发两次点击事件呢?答案是,会的。所以在触发页面入栈的函数中应该添加一个处理语句,在当前页面 A 要将页面 B 入栈时,在处理函数中添加一句 `A.enable = false;`,在 B 页面弹出后,设置 `A.enable = true;`。就不会因为点击过快,触发两次函数,向页面栈压入两个页面了。

> ps: 后来在微信上,拼手速,以极快速度点击**设置**,确实会压入两个或两个以上的**设置**页面。不同安卓机,有不同响应,版本为 **6.2.4**。看来是通病啊。在当前页面压入另一个页面时,是需要时间的,在这个处理过程中,当前页面不做屏蔽处理的话,是十分麻烦的。当然,这种误操作只会有程序猿才能发现。

> 这个 `enable` 属性为真时,允许处理键盘和鼠标事件。详细查看 `Item::enable`。

## 字体大小

字体大小,以及安卓各个硬件上差异,进行适配就有些问题了。如何进行字体大小适配?

直接查看 [Sparrow](https://github.com/GDPURJYFS/Sparrow) 中 `UI.js` 的字体设置大小。使用了 `pointSize` 这个计量单位可以很好的工作在不同屏幕下。可以按照自己需求改动 `UI.js` 中的字体大小值。

## 单个界面

要注意微信在各个屏幕分辨率下,每个可选项的高度,其实是根据字体大小来决定的。例如上下的留白是根据字体的高度。

## 素材

素材获取来源互联网,所有权归腾讯公司所有。

## Model/View

随着研究的深入,我发现,QtQuick 本身提供的 ListModel 不能很好的适应类似于微信这样的界面业务。必须要从 `C++` 中重写对应的逻辑模型。

**TODO**

---

> 查看 [Sparrow 框架](https://github.com/GDPURJYFS/Sparrow)

> 查看[一周 app 计划](https://github.com/GDPURJYFS/A-week-to-develop-android-app-plan)可以了解到更多的安卓开发的问题。


================================================
FILE: main.cpp
================================================
/*!
 * Activity 先于 Qt 加载
 * 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main
 * 2. 在 Qt::main 中注册 Java 的 native 函数 QtBridgingAndroid::notifiedKeyboardRectangle
 * 3. 在 Qt::main 通过调用 Java::QtBridgingAndroid::listenKeyboardHeight 注入监听键盘事件
 * 4. 在 Qt::main 加载 QML。
*/

#include <QApplication>
#include <QQmlApplicationEngine>
#include <qqml.h>
#include <QQmlContext>
#include "Sparrow/qtbridgingandroid.h"
#include "Sparrow/keyboard.h"

#include "src/wellchat/collectionsmodel.h"

int main(int argc, char *argv[])
{
    //! [java register native function]
#ifdef Q_OS_ANDROID
    qDebug() << "QtNative::registerNativeMethod : "
             << QtBridgingAndroid::registerNativeMethodForJava();
#endif
    //! [java register native function]

    QApplication app(argc, argv);


    //! [0]
    app.setApplicationName("WellChat");
    app.setOrganizationDomain("github.com/GDPURJYFS");
    app.setOrganizationName("GDPURJYFS");
    app.setApplicationVersion("0.0.1");
    //! [0]


    QQmlApplicationEngine engine;

    //! [2]  register qml type

    qmlRegisterType<CollectionsModel>("WellChat", 1, 0, "CollectionsModel");

    //! [2]

    //! [3]
    //! import path or imoprt plugin
    engine.addImportPath("qrc:/qml/WellChat");
    //! [3]

    //! [4]
    //! load qml file
    engine.load(QUrl(QStringLiteral("qrc:/qml/WellChat/main.qml")));
    //! [4]

    //! [5]
    QtBridgingAndroid *BridgingAndroid = new QtBridgingAndroid(&engine);

    QQmlContext *context = engine.rootContext();
    context->setContextProperty("BridgingAndroid", BridgingAndroid);

#ifdef Q_OS_ANDROID
    //! [1] 向java安装事件监听,需要在 QApplication 示例化之后
    QtBridgingAndroid::installListener();
    // QQmlEngine: Illegal attempt to connect to Keyboard(0xe20036a0)
    // that is in a different thread than the QML engine
    // QQmlApplicationEngine(0xe0fa1924.
    //! [1]
#endif

    context->setContextProperty("Keyboard", Keyboard::singleton());
    //! [5]

    return app.exec();
}


================================================
FILE: qml/WellChat/BussinessPage/Chat/ChatPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

import Sparrow 1.0
import Sparrow.PopupLayer 1.0

import "./Tuling123.js" as Tuling123

import "../../Component"

Page {
    id: chatPage

    property string username

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        stackView.pop();
        Qt.inputMethod.hide();
    }

    topBar: TopBar {
        id: topBar
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                iconSource: R.R.activeIconBack
                // iconSource: constant.backActiveIcon
                onClicked: {
                    Qt.inputMethod.hide();
                    stackView.pop();
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }

        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: username
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }

            SampleIcon {
                iconSource: R.R.labelIconSettings
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                anchors.right: parent.right
                onClicked: {
                    if(Qt.inputMethod.visible === false) {
                        inputYourNicoName.changeYourNicoName()
                    } else {
                        Qt.inputMethod.visible = false;
                        inputYourNicoName.changeYourNicoName()
                    }
                }
            }

        }

    }

    ///////////////////////////////////////////////////////////////////////////////////

    property string chatContentBuffer: ""

    Lazy {
        id: lazy
    }

    property int readKeyboardHeight: Keyboard.keyboardRectangle.height

    onReadKeyboardHeightChanged: {
        //        console.log("onReadKeyboardHeightChanged, readKeyboardHeight:",
        //                    readKeyboardHeight);
        if(readKeyboardHeight != 0) {
            keyboardHeight = Keyboard.keyboardRectangle.height;
            //            console.log("onReadKeyboardHeightChanged, keyboardHeight:",
            //                        keyboardHeight)
        }
    }

    property int keyboardHeight: 0
    onKeyboardHeightChanged: {
        if(Qt.platform.os === "android") {
            if(keyboardHeight != 0) {
                upAnimation.to = keyboardHeight;
                upAnimation.start();
            }
        }
    }

    NumberAnimation {
        id: upAnimation
        target: chatPage.bottomBarArea
        duration: 50
        from: 0
        properties: "anchors.bottomMargin"
    }

    function inputMethodShowHelper() {
        // 如果是安卓
        if(Qt.platform.os === "android") {
            // 第一次打开
            if(keyboardHeight == 0) {
                Qt.inputMethod.visibleChanged.connect(function() {
                    if(Qt.inputMethod.visible) {
                        Qt.inputMethod.visibleChanged.disconnect(arguments.callee);
                        lazy.startCallback(50, function() {
                            // 动态生成TextArea
                            loader_input.sourceComponent = component_input;
                            loader_input.item.focus = true;
                        });
                    }
                });
                Qt.inputMethod.show();
            } else {
                upAnimation.to = keyboardHeight;
                upAnimation.start();
                lazy.startCallback(50, function() {
                    // 动态生成TextArea
                    loader_input.sourceComponent = component_input;
                    Qt.inputMethod.show();
                });
            }
        } else {
            loader_input.sourceComponent = component_input;
            loader_input.item.focus = true;
        }
    }

    signal keyboardOpen()
    onKeyboardOpen: {
        if(Qt.platform.os === "android") {
            try {
                if(!Keyboard.visible) {
                    // 关闭键盘
                    loader_input.sourceComponent = undefined;
                    upAnimation.to = 0;
                    upAnimation.start();
                }
            } catch(e) {
                console.log(e)
            }
        }
    }

    Component.onCompleted: {
        Qt.inputMethod.visibleChanged.connect(keyboardOpen);
    }

    bottomBar: BottomBar {
        id: bottombar

        focus: true

        RowLayout {
            focus: true
            anchors.fill: parent

            spacing: 5

            IconButton {
                width: topBar.height - 2
                height: topBar.height - 2
                activeIconSource: R.R.activeIconSound
                inactiveIconSource: R.R.inactiveIconSound
            }

            Item {
                focus: true
                Layout.fillWidth: true
                implicitHeight: topBar.height

                IconButton {
                    width: topBar.height * 0.9
                    height: topBar.height * 0.9
                    activeIconSource: R.R.activeIconEmoticon
                    inactiveIconSource: R.R.inactiveIconEmoticon
                    anchors.bottom: parent.bottom
                    anchors.right: parent.right
                    anchors.rightMargin: 10
                }

                Rectangle {
                    FontMetrics {
                        id: fontMetrics
                        font.family: GeneralSettings.generalfontFamily
                        font.pointSize: GeneralSettings.generalFontPointSize
                        font.weight: Font.Thin
                        font.bold: false
                    }
                    width: parent.width - 10
                    anchors.horizontalCenter: parent.horizontalCenter
                    height: 1
                    color: parent.focus? "#71d01d" : "#ccc"
                    anchors.bottom: parent.bottom
                    anchors.bottomMargin: fontMetrics.height * 0.2
                }

                Component {
                    id: component_input
                    // Sample
                    TextArea {
                        id: input

                        //readOnly: true

                        focus: true

                        font.family: GeneralSettings.generalfontFamily
                        font.pointSize: GeneralSettings.generalFontPointSize
                        wrapMode: TextEdit.Wrap
                        backgroundVisible: false

                        Component.onDestruction: {
                            chatContentBuffer = input.text;
                        }

                        Component.onCompleted: {
                            input.text = chatContentBuffer;
                            input.cursorPosition = input.length;
                        }

                        // textFormat: TextEdit.RichText
                        width: parent.width
                        implicitHeight: {
                            if(lineCount >= 2) {
                                (topBar.height - 2) * 2
                            } else {
                                (topBar.height- 2) * lineCount
                            }
                        }

                        // Tracker { }
                    }
                }

                Loader {
                    id: loader_input
                    focus: true

                    anchors.fill: parent
                    onLoaded: {
                        loader_input.item.focus = true;
                        loader_input.item.forceActiveFocus();
                    }

                    MouseArea {
                        anchors.fill: parent
                        visible: {
                            if(loader_input.item) {
                                return loader_input.item.readOnly
                            } else {
                                return true;
                            }
                        }

                        onClicked: inputMethodShowHelper();

                        // 当关闭输入框的时候
                        // 用来显示上次输入的文本
                        SampleLabel {
                            width: parent.width
                            elide: Text.ElideRight
                            text: chatContentBuffer
                            verticalAlignment: Text.AlignVCenter
                            anchors.verticalCenter: parent.verticalCenter
                        }
                    }
                }
            }

            SampleButton {
                id: sendButton
                width: topBar.height * 0.9
                height: topBar.height * 0.9
                Layout.alignment: Qt.AlignRight
                text: qsTr("Send")
                onClicked:  {
                    __sendHelp();
                }
            }

            Item { width: 5; height: 5 }
        }
    }

    /*
    states: [
        //        State {
        //            name: "FixTopBar"
        //            PropertyChanges {
        //                target: chatPage.topBarArea
        //                anchors.topMargin: try {
        //                                       return Keyboard.keyboardRectangle.height;
        //                                   } catch(e) {
        //                                       return 0;
        //                                   }
        //            }
        //        }
        State {
            name: "FixBottomBar"
            PropertyChanges {
                target: chatPage.bottomBarArea
                anchors.bottomMargin: keyboardHeight
            }
        }
    ]

    transitions: [
        //        Transition {
        //            from: "FixTopBar"
        //            to: ""
        //            NumberAnimation {
        //                property: "anchors.topMargin"
        //                duration: 350
        //            }
        //        },
        //        Transition {
        //            from: ""
        //            to: "FixTopBar"
        //            NumberAnimation {
        //                property: "anchors.topMargin"
        //                duration: 350
        //            }
        //        }
        Transition {
            // 回落,键盘收回
            from: "FixBottomBar"
            to: ""
            SequentialAnimation {
                ScriptAction {
                    script: {
                        loader_input.sourceComponent = undefined;
                        console.log("from FixBottomBar to '', readOnly is true");
                    }
                }
                NumberAnimation {
                    property: "anchors.bottomMargin"
                    duration: 150
                }
            }
        },
        Transition {
            from: ""
            to: "FixBottomBar"
            SequentialAnimation {
                NumberAnimation {
                    property: "anchors.bottomMargin"
                    duration: 150
                }
                ScriptAction {
                    script: {
                        loader_input.sourceComponent = component_input;

                        console.log("from '' to FixBottomBar, readOnly is false");
                    }
                }
            }
        }
    ]
    */

    ////////////////////////////////////////////////////////////////////////

    property string userId: "垃圾君"

    ListView {
        id: view
        anchors.fill: parent
        model: chatModels

        delegate: Rectangle {
            width: view.width
            height: chatText.contentHeight * 1.5
            color: "transparent"
            border.color: "black"
            border.width: 1

            SampleLabel {
                id: chatText
                width: parent.width * 0.8 >= chatText.contentWidth
                       ? chatText.contentWidth
                       : parent.width * 0.8

                anchors.right: ChatId != "JiJiZhaZha" ? parent.right : undefined
                text: ChatText
                verticalAlignment: Text.AlignVCenter
                anchors.verticalCenter: parent.verticalCenter
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
            }
        }

        ListModel {
            id: chatModels
            //                ListElement {
            //                    ChatText: "这是文本"
            //                    ChatId: "JiJiZhaZha"
            //                }
            //                ListElement {
            //                    ChatText: "我是垃圾君"
            //                    ChatId: "垃圾君"
            //                }
        }
    }

    property bool __dontFixBottomBar: false

    PopupLayer {
        id: inputYourNicoName
        parent: chatPage
        popupItem.width: chatPage.width * 0.8
        popupItem.height: popupItem.width * 0.5
        onStateChanged: {
            if(inputYourNicoName.state == "Hide") {
                __dontFixBottomBar = false;
            } else {
                __dontFixBottomBar = true;
            }
        }

        RowLayout {
            anchors.fill: parent
            anchors.margins: parent.width * 0.05
            SampleTextField {
                id: getNicoName
                Layout.fillWidth: true
            }
            SampleButton {
                text: qsTr("OK")
                onClicked: {
                    chatPage.userId = getNicoName.text;
                    inputYourNicoName.close();
                    Qt.inputMethod.hide();
                }
            }
        }
        function changeYourNicoName () {
            getNicoName.text = chatPage.userId;
            inputYourNicoName.open();
        }
    }

    function tryToNotify(notifiString) {
        try {
            console.log("will send", notifiString);
            BridgingAndroid.sendNotification(notifiString);
        }catch(e) {
            console.log(e)
        }
    }

    onApplicationStateChanged: {
        if(applicationState == Qt.ApplicationInactive
                || applicationState ==  Qt.ApplicationSuspended
                || applicationState ==  Qt.ApplicationHidden) {
            Qt.inputMethod.hide();
        }
    }

    function __sendHelp() {
        if(loader_input.item.text !== "" ) {
            chatModels.append({
                                  "ChatText": loader_input.item.text,
                                  "ChatId": userId
                              });
            view.positionViewAtIndex(view.count-1, ListView.End );
            Tuling123.sendTextToTuling123(loader_input.item.text,
                                  userId,
                                  function(responseText){
                                      chatModels
                                      .append(
                                           {
                                               "ChatText": responseText,
                                               "ChatId": "JiJiZhaZha"
                                           });
                                      view.positionViewAtIndex(view.count-1, ListView.End );
                                  },
                                  Tuling123.errorCodeHandle
                                  );
            loader_input.item.text = "";
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Chat/Heartbeat.qml
================================================
import QtQuick 2.0

QtObject {
    id: heartbeat

    property alias source: worker.source
    property alias interval: timer.interval
    property alias running: timer.running

    signal message(var msg)
    signal beat()

    property Timer timer: Timer {
        id: timer
        repeat: true
        interval: 1500
        triggeredOnStart: true
        running: false
    }

    property WorkerScript worker: WorkerScript {
        id: worker
    }

    function sendMessage(msg) { worker.sendMessage(msg); }
    function start() { timer.start(); }
    function stop() { timer.stop(); }

    Component.onCompleted: {
        worker.message.connect(message);
        timer.triggered.connect(beat);
    }
}



================================================
FILE: qml/WellChat/BussinessPage/Chat/Lazy.qml
================================================
import Resource 1.0 as R

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2

import Sparrow 1.0
import Sparrow.PopupLayer 1.0

import "../../Component"

Timer {
    id: lazy
    interval: 100
    running: false
    repeat: false
    property var callback
    onTriggered: {
        try {
            callback();
        } catch(e) {
            
        }
    }
    function startCallback(time, callback) {
        time = time || 500;
        callback = callback || function() { };
        interval = time;
        lazy.callback = callback;
        lazy.start();
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Chat/Tuling123.js
================================================
.pragma library

// callback(responseText)
// err(errorCode)
function sendTextToTuling123(text, chatUserId, callback, err) {
    // http://www.tuling123.com/openapi/api?key=b77b735b2797bc613e7623f4406fe342&info=你好
    var host = "http://www.tuling123.com/openapi/api?";

    // 这里填写你在图灵机器人网站申请的apiKey
    // 现在图灵机器人网站是免费申请的哦。
    var apiKey = "b77b735b2797bc613e7623f4406fe342";
    var info = text;

    var dataTemplate = {
        "code": 10000,              // 返回的错误码
        "text": "回复的内容",
        "url": "",                  // 返回单条链接
        "list": []                  // 返回多条信息
    }

    var xhr = new XMLHttpRequest;
    xhr.onreadystatechange = function() {
        if(xhr.readyState == xhr.DONE) {
            console.log("xhr.responseText: ", xhr.responseText);
            try {
                var dataObject = JSON.parse(xhr.responseText);
                if(!isErrorCode(dataObject.code)) {
                    callback(dataObject.text);
                } } catch(e) {
                console.log(e);
            }

        }
    }
    xhr.open("GET", host+ "key=" + apiKey +"&userid=" + chatUserId +"&info="+info );
    xhr.send()
}


function isErrorCode(code) {
    var errorCodes = [
                {
                    "code":40001,
                    "description":"参数key长度错误(应该是32位)"
                },
                {
                    "code":40002,
                    "description":"请求内容info为空"
                },
                {
                    "code":40003,
                    "description":"key错误或帐号未激活"
                },
                {
                    "code":40004,
                    "description":"当天请求次数已使用完"
                },
                {
                    "code":40005,
                    "description":"暂不支持所请求的功能"
                },
                {
                    "code":40006,
                    "description":"图灵机器人服务器正在升级"
                },
                {
                    "code":40007,
                    "description":"数据格式异常"
                },
            ];
    for(var iter in errorCodes) {
        if(errorCodes[iter].code === code) {
            return true;
        }
    }
    return false;
}

function errorCodeHandle(code) {

    var errorCodes = [
                {
                    "code":40001,
                    "description":"参数key长度错误(应该是32位)"
                },
                {
                    "code":40002,
                    "description":"请求内容info为空"
                },
                {
                    "code":40003,
                    "description":"key错误或帐号未激活"
                },
                {
                    "code":40004,
                    "description":"当天请求次数已使用完"
                },
                {
                    "code":40005,
                    "description":"暂不支持所请求的功能"
                },
                {
                    "code":40006,
                    "description":"图灵机器人服务器正在升级"
                },
                {
                    "code":40007,
                    "description":"数据格式异常"
                },
            ];
    for(var iter in errorCodes) {
        if(errorCodes[iter].code === code) {
            console.log(errorCodes[iter].description);
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Chat/heart.js
================================================
// .pragma library

// 心跳包

// to include static singleton mess_id
Qt.include("./storage.js")

WorkerScript.onMessage = function(message) {
    var model = message.listModel;

    var doc = new XMLHttpRequest;
    doc.open("POST", "http://cnzxzc.tunnel.mobi/qyvlik/sendMess");
    doc.onreadystatechange = function () {
        if (doc.readyState === XMLHttpRequest.DONE) {
            console.log("on message, model:", model);
            console.log("XMLHttpRequest DONE");
            console.log("====轮询结果=======,mess_id:", mess_id);
            console.log(doc.responseText);
            console.log("====轮询结果=======");
            try {
                var content = JSON.parse(doc.responseText);
                if(content.hasOwnProperty("mess_id")) {
                    mess_id = content.mess_id;
                    timestamp = content.timestamp;
                    var item = {
                        "chatContext": content.content
                    }
                    model.append(item);
                    model.sync();
                }
            } catch(e) {
                console.log(e);
            }
        }
    }
    var lunxun = {
        "timestamp": timestamp,
        "room_id":"1",
        "mess_id":mess_id
    }
    doc.send(JSON.stringify(lunxun));


}


================================================
FILE: qml/WellChat/BussinessPage/ChatsView.qml
================================================

import BussinessPage 1.0 as BR

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1

import "../Component"

import Sparrow 1.0

Page {
    id: chatsView
    title: "FriendList"
    color: "white"
    property int headPrtraitSize: 90
    signal openNewChat(int userid, string username)

    onOpenNewChat: {
        if(__find(username) !== null) {
            // go to the chat page
            __LoadChatPage(userid, name);
        } else {
            chatItemsModel.append(
                        {
                            "chatTime": (new Date).toDateString(),
                            "chatName":username,
                            "chatisBool": false,
                            "chatContext":userid
                        });
            // go to the chat page
            __LoadChatPage(userid, username);
        }
    }

    ListView {
        id: listView
        width: chatsView.width
        height: chatsView.height
        model: chatItemsModel
        highlightMoveDuration: 1000
        highlightRangeMode: ListView.ApplyRange

        // 控制滚动速度
        maximumFlickVelocity: 5000
        /////////////////////////////////////////////////////////////////////////////////////////
        /*
        highlightRangeMode: ListView.StrictlyEnforceRange
        readonly property alias topSideBarIsOpen: listView.__topSideBarIsOpen
        property bool __topSideBarIsOpen: false
        onAtYBeginningChanged: {
            try {
                if(listView.atYBeginning) {
                    console.log(-listView.contentY, listView.headerItem.height)
                    if( -contentY > listView.headerItem.height) {
                        listView.__topSideBarIsOpen = true;
                    }
                } else {
                    listView.__topSideBarIsOpen = false;
                }
            } catch(e) {    }
        }

        onTopSideBarIsOpenChanged: {
            if(listView.topSideBarIsOpen) {
                listView.highlightRangeMode = ListView.ApplyRange   // 焦点Item允许停止的位置
            } else {
                listView.highlightRangeMode  = ListView.StrictlyEnforceRange
            }
        }

        header: Rectangle {
            id: headerItem
            width: listView.width;
            height: listView.height
            color: "black"
        }
        //*/
        /////////////////////////////////////////////////////////////////////////////////////////
        add: Transition {
            NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
            NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
        }
        move: Transition {
            NumberAnimation { properties: "x,y"; duration: 800; easing.type: Easing.OutBack }
        }
        displaced: Transition {
            NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
        }
        states: [
            State {
                name: "ShowBar"
                when: listView.movingVertically
                PropertyChanges { target: verticalScrollBar; opacity: 1 }
            },
            State {
                name: "HideBar"
                when: !listView.movingVertically
                PropertyChanges { target: verticalScrollBar; opacity: 0 }
            }
        ]

        transitions: [
            Transition {
                from: "ShowBar"
                to: "HideBar"
                NumberAnimation { properties: "opacity"; duration: 400 }
            },
            Transition {
                from: "HideBar"
                to: "ShowBar"
                NumberAnimation { properties: "opacity"; duration: 400 }
            }
        ]

        ScrollBar {
            id: verticalScrollBar
            width: 10 * Screen.devicePixelRatio
            height: listView.height - width
            anchors.right: listView.right
            orientation: Qt.Vertical
            position: listView.visibleArea.yPosition
            pageSize: listView.visibleArea.heightRatio
        }

        delegate: Rectangle {
            id: chatItem
            // chatItem

            property int chatItemHeight: chatItemRowLayout.height

            width: chatsView.width
            height: chatItem.chatItemHeight
            color: "transparent"
            border.width: 1
            border.color: "#ccc"
            state: "UnSelected"
            states: [
                State {
                    name: "Selected"
                    PropertyChanges { target:chatItem; color: "#ccc" }
                },
                State {
                    name: "UnSelected"
                    PropertyChanges { target:chatItem; color: "transparent" }
                }
            ]

            transitions: [
                Transition {
                    from: "Selected"
                    to: "UnSelected"
                    NumberAnimation { properties: "color"; duration: 400 }
                },
                Transition {
                    from: "UnSelected"
                    to: "Selected"
                    NumberAnimation { properties: "color"; duration: 400 }
                }
            ]

            RowLayout {
                id: chatItemRowLayout
                width: parent.width
                height: (chatItemName.contentHeight+chatItemContext.contentHeight) * 1.5
                anchors.margins: spacing
                Image {
                    width: chatItem.chatItemHeight
                    height: chatItem.chatItemHeight
                    anchors.verticalCenter: parent.verticalCenter
                    sourceSize.width: chatItem.chatItemHeight - 2
                    sourceSize.height: chatItem.chatItemHeight - 2
                    source: "../Resource/tests/tests001.jpg"
                    fillMode: Image.PreserveAspectFit
                }
                ColumnLayout {
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    RowLayout {
                        Layout.fillHeight: true
                        Layout.fillWidth: true
                        SampleLabel { id: chatItemName; Layout.fillWidth: true; text: name }
                        SampleLabel { id: chatItemTime; Layout.fillWidth: true; text: chatTime }
                    }
                    RowLayout {
                        Layout.fillHeight: true
                        Layout.fillWidth: true
                        SampleLabel { id: chatItemContext; Layout.fillWidth: true; text: chatContext }
                        SampleLabel { id: chatItemisBool;Layout.fillWidth: true; text: chatisBool }
                    }
                }
            }

            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.LeftButton | Qt.RightButton
                onPressAndHold: {
                    chatItem.state = "Selected";
                    chatItemMenu.aboutToHide.connect(function(){
                        chatItemMenu.aboutToHide.disconnect(arguments.callee);
                        chatItem.state = "UnSelected";
                    });
                    chatItemMenu.aboutToShow.connect(function(){
                        chatItemMenu.aboutToShow.disconnect(arguments.callee);
                        chatItem.state = "Selected";
                    });
                    chatItemMenu.chatItemIndex = index;
                    chatItemMenu.popup();
                }
                onClicked: {
                    __LoadChatPage(1, name);
                }
            }
        }

        Menu {
            id: chatItemMenu
            property int chatItemIndex: 0
            MenuItem {
                text: qsTr("Delete conversation")
                onTriggered: {
                    listView.model.remove(chatItemMenu.chatItemIndex);
                }
            }
            MenuItem {
                text: qsTr("Sticky on top")
                onTriggered: {
                    listView.model.move(chatItemMenu.chatItemIndex, 0, 1);
                }
            }
            MenuItem {
                text: qsTr("Clear")
                onTriggered: {
                    listView.model.clear();
                }
            }
        }

        ListModel {
            id: chatItemsModel
            //            ListElement {
            //                username: "Apple"
            //                chatContext: "2333"
            //                chatTime: 2.45
            //                chatisBool: true
            //            }

            /*
                  联系人名字
                  聊天记录
                  时间
                  是否
                 */
            Component.onCompleted: {
                for(var i=0; i<1; i++) {

                    chatItemsModel
                    .append(
                         {
                             "chatTime": i,
                             "name":"忍野忍",
                             "chatisBool": false,
                             "chatContext":"233" + i
                         });
                }
            }
        }
    }

    function __find(name) {
        if(chatItemsModel.count == 0) return null;
        var chatItemsCount = chatItemsModel.count;
        for(var i=0; i<chatItemsCount; i++) {
            // console.log("chatItemsModel.get(i).chatName: ", chatItemsModel.get(i).chatName, ", name: ",name);
            if(chatItemsModel.get(i).chatName === name) {
                return chatItemsModel.get(i);
            }
        }
        return null;
    }

    function __LoadChatPage(userid, username){
        __PushPage(BR.R.chatChatPage, {username: username} );
    }

}



================================================
FILE: qml/WellChat/BussinessPage/Contacts/ContactsListView.qml
================================================
import QtQuick 2.5
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
import Sparrow 1.0 as Sparrow

Rectangle {
    id: root
    width: 400
    height: 600
    color: "transparent"

    property ListView mainListView: null

    property alias model: listView.model
    property alias delegate: listView.delegate
    property alias section: listView.section

    ListView {
        id: listView
        anchors.fill: parent
        snapMode: ListView.NoSnap
        maximumFlickVelocity: 5000
        highlightRangeMode: ListView.NoHighlightRange
    }

    function getSectionHeadIndex(sectionModel, role, sectionText) {
        try {
            var count = sectionModel.count;
            var iter = 0;
            while(iter < count) {
                if(sectionModel.get(iter)[role].charAt(0) === sectionText) {
                    return iter;
                }
                ++iter;
            }
        } catch(e) {
            console.log(e);
        }
        return 0;
    }

    Rectangle {
        id: bar
        height: parent.height
        width: Screen.pixelDensity * 5 // 2mn
        anchors.right: parent.right
        color: Qt.rgba(0.5, 0.5, 0.5, 0.5)
        opacity: 0.2

        ColumnLayout {
            anchors.fill: parent
            Repeater {
                id: repeater

                model: ["↑", "☆","a", "b", "c", "d", "e", "f"
                    , "g", "h", "i", "j", "k", "l", "m", "n",
                    "o", "p", "q", "r", "s", "t", "u", "v", "w",
                    "x", "y", "z"]

                    Text {
                        anchors.horizontalCenter: parent.horizontalCenter
                        text: repeater.model[index]
                        font.pointSize: Sparrow.UI.SmallFontPointSize - 1
                    }

            }
        }

        MouseArea {
            anchors.fill: parent

            onReleased: {
                listView.highlightRangeMode = ListView.NoHighlightRange;
                listView.snapMode = ListView.NoSnap;
                mainListView.interactive = true;
                bar.opacity = 0.2;
                showText.close();
            }

            onPositionChanged: {
                bar.opacity = 0.8;
                var itemHeight = parent.height / repeater.model.length;
                var pos = Math.floor(mouse.y / itemHeight);
                try {
                    mainListView.interactive = false;
                    showText.show(repeater.model[pos]);
                    listView.highlightRangeMode = ListView.StrictlyEnforceRange;
                    listView.snapMode = ListView.SnapOneItem;
                    listView.currentIndex =
                            getSectionHeadIndex(listView.model,
                                                listView.section.property,
                                                repeater.model[pos]);
                } catch(e) {
                    listView.highlightRangeMode = ListView.NoHighlightRange;
                    listView.snapMode = ListView.NoSnap;
                    mainListView.interactive = true;
                    console.log(pos);
                    console.log(e)
                }
            }
        }
    }


    Rectangle {
        id: showText
        width: Screen.pixelDensity * 20
        height: Screen.pixelDensity * 20
        color: Qt.rgba(0.8, 0.8,0.8, 0.8)
        anchors.centerIn: parent
        property alias text: text.text
        visible: false
        Sparrow.SampleLabel {
            id: text
            anchors.centerIn: parent
        }
        function show(t) {
            showText.text = t;
            showText.visible = true;
        }
        function close() {
            showText.text = "";
            showText.visible = false;
        }
    }

}



================================================
FILE: qml/WellChat/BussinessPage/ContactsView.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import "../Component"
import "./Contacts"

import Sparrow 1.0

Page {
    id: contactsView

    title: qsTr("Contacts")
    property int headPrtraitSize: 50

    property ListView mainListView: null

    ContactsListView {
        mainListView: contactsView.mainListView
        width: contactsView.width
        height: contactsView.height

        section.property: "name"
        section.criteria: ViewSection.FirstCharacter
        section.delegate: Rectangle {
            width: contactsView.width
            height: childrenRect.height
            color: "transparent"

            SampleLabel {
                text: section
            }
        }
        model: ListModel {
            id: personModel

            Component.onCompleted: {
                personModel
                var d = ["☆","a1","a1","a1", "a1","a1","a1","a1","a1","a1","a1","a1",
                         "b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
                         "b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
                         "b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2","b2",
                         "b2","c3","c3","c3","c3","c3","c3","c3","c3","c3","c3","d",
                         "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
                         "q", "r", "s", "t", "u", "v", "w","x24", "x24","x24","x24","x24",
                         "x24","x24","x24","x24","x24","x24","x24","x24","x24","x24","x24",
                         "x24","x24","x24","y", "z"];
                for(var i=0;i<d.length; i++) {
                    personModel.append({"name": d[i]});
                }
            }

        }

        delegate: ColumnLayout {
            width: contactsView.width
            height: l.height
            IconLabel {
                id: l
                spacing: 10
                Layout.fillWidth: true;
                iconSource: R.R.testPic
                labelText: qsTr("哔哩哔哩")
                onPressAndHold: {
                    menu.chatItemIndex = index;
                    menu.popup();
                }
                Separator {
                    color: "#999"; orientation: Qt.Horizontal ;
                    length: parent.width * 0.8
                    anchors.bottom: parent.bottom
                    anchors.horizontalCenter: parent.horizontalCenter
                }

                onClicked: {
                    console.log("go to the person profile");
                    __PushPage(BR.R.profilePage);
                }
            }
        }

        Menu {
            id: menu
            property int chatItemIndex: 0
            MenuItem {
                text: qsTr("Set Remarks and Tags")
                onTriggered: {

                }
            }
        }
    }
}



================================================
FILE: qml/WellChat/BussinessPage/Discover/MomentsPage/MomentsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: momentsPage
    title: "moments"
    color: "#22292c"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        if(webPage.canGoBack) {
            webPage.goBack();
        } else {
            try { stackView.pop(); }
            catch(e) { console.log(e); }
        }
    }

    Constant {
        id: constant
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                iconSource: R.R.activeIconBack
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            Label {
                text: momentsPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: constant.middleFontPointSize
            }
        }
    }

    Item {
        anchors.fill: parent

        Item {
            id: loadProgressArea
            width: momentsPage.width
            height: Screen.pixelDensity
            visible: webPage.loadProgress != 100
            Rectangle {
                height: parent.height
                width: parent.width * (100/webPage.loadProgress)
                color: "green"
            }
        }

        WebPage {
            id: webPage
            width: momentsPage.width
            anchors.top: loadProgressArea.bottom
            anchors.bottom: parent.bottom
            url: "https://github.com/GDPURJYFS/WellChat"
//            {
//                if(Qt.platform.os == "android") {
//                    return Qt.resolvedUrl("file:///android_asset/html/index.html");
//                }  else  {
//                    return "../../../Resource/html/index.html";
//                }
//            }
        }
    }
}



================================================
FILE: qml/WellChat/BussinessPage/DiscoverPage.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import "../Component"
import "./Personal"

import Sparrow 1.0

Page {
    id: discoverPage
    title: qsTr("Discover")
    color: "#ebebeb"

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content

            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)


            FontMetrics {
                id: fontMetrics
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: GeneralSettings.generalFontPointSize
            }

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: fontMetrics.height
                Item {  width: parent.spacing;  height: parent.height }

                IconLabel {
                    Layout.fillWidth: true
                    iconSource: R.R.labelIconMoments
                    labelText:  qsTr("Moments")
                    onClicked: {
                        __PushPage(BR.R.discoverMomentsPage)
                    }

                    Image {
                        id: momentsCurrentActiveFriend
                        anchors.right: parent.right
                        anchors.verticalCenter: parent.verticalCenter
                        anchors.rightMargin: column.spacing
                        width: parent.height
                        height: parent.height
                        sourceSize: Qt.size(width, height)
                        source: R.R.testPic
                    }

                } // First Group

                Rectangle {
                    id: colmnLayout2Parent
                    Layout.fillWidth: true
                    height: columnLayout2.height
                    color: "white"
                    ColumnLayout {
                        id: columnLayout2
                        width: parent.width
                        spacing: 0
                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: R.R.labelIconScanQRCode
                            labelText:  qsTr("Scan QR Code")
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: R.R.labelIconShake
                            labelText:  qsTr("Shake")
                        }
                    }
                } // Second Group


                Rectangle {
                    Layout.fillWidth: true
                    height: columnLayout3.height
                    color: "white"
                    ColumnLayout {
                        id: columnLayout3
                        width: parent.width
                        spacing: 0
                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: R.R.labelIconPeopleNearby
                            labelText:  qsTr("People Nearby")
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: R.R.labelIconDriftBottle
                            labelText:  qsTr("Drift Bottle")
                        }
                    }
                } // Thrid Group

                IconLabel {
                    Layout.fillWidth: true
                    iconSource: R.R.labelIconGames
                    labelText:  qsTr("Games")
                } // First Group
            } // Main ColumnLayout
        } // content
    } // ScrollView
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/FavoritesPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Layouts 1.1

import "../../Component"
import "./Settings"

import Sparrow 1.0

import WellChat 1.0

Page {
    id: myPostPage
    title: qsTr("My Post")
    color: "white"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                    // console.log(x, y)
                }

                //! [0] fix the bug
                // 在本页面压入一个页面之后再弹出
                // x 的值会变成 180
                // 需要将其设置回 0
                onXChanged: {
                    if(x != 0 ) {
                        x = 0
                    }
                }
                //! [0] fix the bug

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: myPostPage.title
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ListView {
        id: listView
        anchors.fill: parent
        clip: true
        maximumFlickVelocity: 5000
        model: CollectionsModel {
            id: collectionsModel

            //            enum CollectionRole {
            //                Author        // 作者
            //                CreateTime,   // 创建时间
            //                Title,        // 标题
            //                Source,       // 来源地址:http://baidu.com
            //                SourceName,   // 来源名字:baidu
            //                Summary,      // 摘要
            //                CollectionType// 收藏的类型,例如链接,音乐,图片等
            //            };

            Component.onCompleted: {
                console.log();
            }

        }
        spacing: 30

        delegate: RowLayout {
            width:  myPostPage.width
            SampleLabel {
                text: Author
            }
            SampleLabel {
                Layout.fillWidth: true
                text: "Author " + Author + "\n"
                      + "CreateTime: " + CreateTime + "\n"
                      + "Title: " + Title + "\n"
                      + "Source: " + Source + "\n"
                      + "SourceName: " + SourceName + "\n"
                      + "Summary: " + Summary + "\n"
                      + "CollectionType: " + CollectionType + "\n"
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
            }
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/MyPostsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import "../../Component"
import "./Settings"

import Sparrow 1.0

Page {
    id: myPostPage
    title: qsTr("My Post")
    color: "white"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                    // console.log(x, y)
                }

                //! [0] fix the bug
                // 在本页面压入一个页面之后再弹出
                // x 的值会变成 180
                // 需要将其设置回 0
                onXChanged: {
                    if(x != 0 ) {
                        x = 0
                    }
                }
                //! [0] fix the bug

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: myPostPage.title
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ListView {
        id: listView
        anchors.fill: parent
        clip: true
        maximumFlickVelocity: 5000
        model: 100
        spacing: 30
        header: Item {
            width: myPostPage.width
            height: fengmian.height + (touxiang.height)
            Image {
                id: fengmian
                source: R.R.testPic
                sourceSize.width: myPostPage.width
                width: myPostPage.width
                fillMode: Image.PreserveAspectCrop
            }
            Image {
                id: touxiang
                anchors.right: parent.right
                anchors.rightMargin: touxiang.height * 0.2
                anchors.bottom: parent.bottom
                anchors.bottomMargin: touxiang.height / 2
                source: R.R.testPic
                sourceSize.width: myPostPage.width * 0.23
            }
        }
        delegate: RowLayout {
            width:  myPostPage.width
            SampleLabel {
                text: "今天"
            }
            Image {
                source: R.R.testPic
                sourceSize.width: myPostPage.width * 0.23
                fillMode: Image.PreserveAspectCrop
            }
            SampleLabel {
                Layout.fillWidth: true
                text: "正文之今天选课,炸了dddddddddddddddddddddddddddddddddddddddddddddddd炸了炸了炸了"
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
            }

        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/AboutPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: aboutPage
    title: qsTr("My Account")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: aboutPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }


                Image {
                    anchors.horizontalCenter: parent.horizontalCenter
                    width: page.width * 0.4
                    height: page.width * 0.4
                    sourceSize: Qt.size(page.width * 0.4, page.width * 0.4)
                    source: R.R.testPic
                }

                SettingsGroup {
                    Layout.fillWidth: true
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Rete WellChat")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Features")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Help & Feedback")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Version Update")
                        Label {
                            text: qsTr("1.0.0")
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                        }
                    }
                }

                Label {
                    Layout.fillWidth: true
                    text: qsTr("Terms and Privacy")
                    color: "blue"
                    font.family: GeneralSettings.generalfontFamily
                    horizontalAlignment: Text.AlignHCenter
                    font.pointSize: constant.smallFontPointSize + 2
                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                }

                Label {
                    Layout.fillWidth: true
                    text: qsTr("Copyright © 2015 qyvlik\n All Rights Reserved.")
                    color: "#666"
                    font.family: GeneralSettings.generalfontFamily
                    font.pointSize: constant.smallFontPointSize + 2
                    horizontalAlignment: Text.AlignHCenter
                    wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                }

            } // Main ColumnLayout
        } // content
    } // ScrollView
}



================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/ChatSettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0
import Sparrow.PopupLayer 1.0

import "../../../Component"

Page {
    id: chatSettnigsPage
    title: qsTr("Chat")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: chatSettnigsPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Turn Off Speaker")
                        Switch {
                            checked: false
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Press Enter to Send")
                        Switch {
                            checked: false
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Background")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("My Stickers")
                    }

                } // First Settings Ground

                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Backup/Restore Chat History")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Clear Chat History")
                        onClicked: dialog.open()
                    }
                } // Second Settings Ground
            } // Main ColumnLayout
        } // content
    } // ScrollView

    PopupLayer {
        id: dialog
        popupItem.radius: chatSettnigsPage.width * 0.05
        SampleButton {
            anchors.centerIn: parent
            text: qsTr("Clear?")
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/DoNotDisturbSettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: notificationsPage
    title: qsTr("Do Not Disturb")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: notificationsPage.title
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }


    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }


                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Notificatons")
                        Switch {
                            id: switch1
                            checked: false
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Item {
                        width: notificationsPage.width
                        height: label.height
                        Label {
                            id: label
                            anchors.right: parent.right
                            anchors.left: parent.left
                            anchors.margins: 10
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("If enabled, you won't be notified about new messages during the hours set.")
                        }
                    }

                    Separator {
                        visible: switch1.checked
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        visible: switch1.checked
                        Layout.fillWidth: true
                        labelText:  qsTr("Start")

                        Label {
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("11:00 PM")
                        }
                    }

                    Separator {
                        visible: switch1.checked
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        visible: switch1.checked
                        Layout.fillWidth: true
                        labelText:  qsTr("End")

                        Label {
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("8:00 AM")
                        }
                    }
                }

            }  // Main ColumnLayout
        } // content
    } // ScorllView
}




================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/GeneralSettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: generalSettingsPage
    title: qsTr("General")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            Label {
                text: generalSettingsPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: constant.middleFontPointSize
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true

                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Landscape Display")
                            Switch {
                                checked: true
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Low-bitrate Recording")
                            Switch {
                                checked: true
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Low-bitrate Recording")
                            Label {
                                text: qsTr("3G / 4G and Wi-Fi")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                                font.pointSize: constant.smallFontPointSize + 2
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Auto-Update WellChat")
                            Label {
                                text: qsTr("Never")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                                font.pointSize: constant.smallFontPointSize + 2
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Language")
                            Label {
                                text: qsTr("English")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                                font.pointSize: constant.smallFontPointSize + 2
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Font Size")
                            Label {
                                text: qsTr("Standard")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                                font.pointSize: constant.smallFontPointSize + 2
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Features")
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Data Usage")
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Web WellChat")
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }
                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Manage Storage")
                        }
                } // First Settings Group
            } // Main ColumnLayout
        } // content
    } // ScrollView
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/MyAccountSettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: myAccountSettingsPage
    title: qsTr("My Account")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            Label {
                text: myAccountSettingsPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: constant.middleFontPointSize
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true
                    title: qsTr("Account")

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Well Chat ID")
                        Label {
                            text: "qyvlik"
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("QQ ID")
                        Label {
                            text: "1234567890"
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Phone")
                        Label {
                            text: "13588880000"
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Email")
                        Label {
                            text: qsTr("Verified")
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                        }
                    }
                } // First Settings Group

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true
                    title: qsTr("Security")
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Voiceprint")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Password")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Account Protection")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Mobile Security")
                    }

                    Item {
                        width: myAccountSettingsPage.width
                        height: label.height
                        Label {
                            id: label
                            anchors.right: parent.right
                            anchors.left: parent.left
                            anchors.margins: 10
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("Go to the Well Chat Security Center for account security issues.")
                        }
                    }

                } // Second Settings Group

            } // Main ColumnLayout
        } // content
    } // ScrollView
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/NotificationsSettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: notificationsPage
    title: qsTr("Notifications")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: notificationsPage.title
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }


                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("New Message Alerts")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Notificatons")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Item {
                        width: notificationsPage.width
                        height: label.height
                        Label {
                            id: label
                            anchors.right: parent.right
                            anchors.left: parent.left
                            anchors.margins: 10
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("If turn off, notifications for WellChat messages will not contain the sender and summary.")
                        }
                    }
                }


                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Sound")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Alert Sound")

                        Label {
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("auto")
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("In-App Vibrate")                // 震动
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }


                }


                SettingsGroup {
                    Layout.fillWidth: true
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Moments Upadates")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Item {
                        width: notificationsPage.width
                        height: labe2.height
                        Label {
                            id: labe2
                            anchors.right: parent.right
                            anchors.left: parent.left
                            anchors.margins: 10
                            color: "#666"
                            font.family: GeneralSettings.generalfontFamily
                            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            font.pointSize: constant.smallFontPointSize + 2
                            text: qsTr("if turned off, you will not see a red dot for friends' new messages.")
                        }
                    }
                }
            }
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/PrivacySettingsPage.qml
================================================
import Resource 1.0 as R

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../../../Component"

Page {
    id: privacySettingsPage
    title: qsTr("Privacy")
    color: "#ccc"

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    Constant {  id: constant  }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            Label {
                text: privacySettingsPage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: constant.middleFontPointSize
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content

            //width: Math.max(page.viewport.width, column.implicitWidth + 2 * column.spacing)
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Friend Confirmation")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Find QQ Contacts")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Find Mobile Contacts")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Blocked List")
                    }

                } // First Setting Group


                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Find Me by WeChat ID")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Find Me by Phone No.")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Find Me By QQ ID")                // 震动
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }

                    }
                }  // Second Setting Group

                SettingsGroup {
                    Layout.fillWidth: true
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Don't Share My Moments")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Hide User's Moments")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Moments Groups")
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Public Moments")
                        Switch {
                            checked: true
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.rightMargin: column.spacing
                        }
                    }
                } //  Third Setting Group

            } // Main ColumnLayout
        } // content
    } // ScollView
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/Settings/SettingsGroup.qml
================================================
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import "../../../Component"
import Sparrow 1.0

Item  {
    id: settingsGroup

    property alias title: title.text
    property alias backgroundColor: background.color
    property alias spacing: columnLayout.spacing
    default property alias data: columnLayout.data

    height: columnLayout.implicitHeight + titleArea.height

    Rectangle {
        id: titleArea
        color: "transparent"
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.top: parent.top
        height: title.text != "" ? title.height : 1

        SampleLabel {
            id: title
            color: "#666"
            anchors.left: parent.left
            anchors.leftMargin: 20
            anchors.verticalCenter: parent.verticalCenter
        }
    }

    Rectangle {
        id: background
        color: "white"
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.top: parent.top
        anchors.topMargin: titleArea.height
        height: parent.height
    }

    ColumnLayout {
        id: columnLayout
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.top: parent.top
        anchors.topMargin: titleArea.height
        spacing: 0
    }
}


================================================
FILE: qml/WellChat/BussinessPage/Personal/SettingsPage.qml
================================================
import Resource 1.0 as R
import BussinessPage 1.0 as BR

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import "../../Component"
import "./Settings"

import Sparrow 1.0
import Sparrow.PopupLayer 1.0
import Sparrow.PopupLayer.Delegate 1.0

Page {
    id: personalPage
    title: qsTr("Personal")

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: R.R.activeIconBack
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                    // console.log(x, y)
                }

                //! [0] fix the bug
                // 在本页面压入一个页面之后再弹出
                // x 的值会变成 180
                // 需要将其设置回 0
                onXChanged: {
                    if(x != 0 ) {
                        x = 0
                    }
                }
                //! [0] fix the bug

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: personalPage.title
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                SettingsGroup {
                    Layout.fillWidth: true

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Notificatons")
                        onClicked: {
                            __PushPage(BR.R.personalSettingsNotificationsSettingsPage)
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Do Not Disturb")

                        onClicked: {
                             __PushPage(BR.R.personalSettingsDoNotDisturbSettingsPage);
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Chat")
                        onClicked: {
                            __PushPage(BR.R.personalSettingsChatSettingsPage)
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Privacy")
                        onClicked: {
                            __PushPage(BR.R.personalSettingsPrivacySettingsPage)
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("General")
                        onClicked: {
                            __PushPage(BR.R.personalSettingsGeneralSettingsPage)
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("My Account")
                        onClicked: {
                            __PushPage(BR.R.personalSettingsMyAccountSettingsPage)
                        }
                    }
                } // First Settings Group

                SettingsGroup {
                    Layout.fillWidth: true
                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("About")
                        onClicked: {
                             __PushPage(BR.R.personalSettingsAboutPage)
                        }
                    }

                    Separator {
                        Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                        color: "#666"; orientation: Qt.Horizontal ;
                        anchors.horizontalCenter: parent.horizontalCenter
                    }

                    IconLabel {
                        Layout.fillWidth: true
                        labelText:  qsTr("Log Out")
                        onClicked: dialog.open()
                    }
                }
            }// First Settings Group
        } // content
    } // ScrollView

    PopupLayer {
        id: dialog
        popupItem.color: "white"
        popupItem.radius: personalPage.width * 0.05
        SampleButton {
            anchors.centerIn: parent
            text:qsTr("Log Out?")
            onClicked: {
                dialog.close()
            }
        }
    }
}


================================================
FILE: qml/WellChat/BussinessPage/PersonalPage.qml
================================================
import BussinessPage 1.0 as BR

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../Component"

Page {
    id: personalPage
    title: qsTr("Personal")
    color: "#ebebeb"

    Constant {  id: constant  }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            FontMetrics {
                id: fontMetrics
                font.family: GeneralSettings.generalfontFamily
                font.pointSize: GeneralSettings.generalFontPointSize
            }

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: fontMetrics.height

                Item {  width: parent.spacing;  height: parent.height }

                Rectangle {
                    Layout.fillWidth: true
                    height: rowLayout1.height + 10

                    RowLayout {
                        id: rowLayout1
                        width: parent.width
                        anchors.verticalCenter: parent.verticalCenter
                        spacing: Screen.pixelDensity * 1.5 // 1.5mn

                        Item {  width: parent.spacing;  height: parent.height }

                        Image {
                            height: column1.height * 1.8
                            width: column1.height * 1.8
                            sourceSize: Qt.size(width, height)
                            source: constant.testPic
                        }

                        ColumnLayout {
                            id: column1
                            Layout.fillHeight: true
                            Row {
                                spacing: 10
                                SampleLabel {
                                    id: personName
                                    text: "小屁孩"
                                }
                                Image {
                                    height: personName.height
                                    width: personName.height
                                    sourceSize: Qt.size(width, height)
                                    source: constant.maleSampleIcon
                                }
                            }
                            SampleLabel {
                                id: showId
                                text: qsTr("ID: qyvlik")
                                color: "#888"
                            }
                            //                            SampleLabel {
                            //                                id: showNick
                            //                                text: "昵称: " + "qyvlik"
                            //                                color: "#888"
                            //                            }
                        }

                        Item { Layout.fillWidth: true }

                    } // rowLayout1
                }

                Rectangle {
                    id: colmnLayout2Parent
                    Layout.fillWidth: true
                    height: columnLayout2.height
                    color: "white"
                    ColumnLayout {
                        id: columnLayout2
                        width: parent.width
                        spacing: 0
                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: constant.myPostsLabelIcon
                            labelText:  qsTr("My Posts")
                            onClicked: {
                                __PushPage(BR.R.personalMyPostsPage);
                                // __PushPage(Qt.resolvedUrl("./Personal/MyPostsPage.qml"), {} );
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            Layout.fillWidth: true
                            iconSource: constant.favoritesLabelIcon
                            labelText:  qsTr("Favorites")
                            onClicked: {
                                __PushPage(BR.R.personalFavoritesPage, {} );
                                //                                 __PushPage(Qt.resolvedUrl("./Personal/FavoritesPage.qml"), {} );

                            }
                        }
                    }
                }

                IconLabel {
                    Layout.fillWidth: true
                    iconSource: constant.walletLabelIcon
                    labelText:  qsTr("Wallet")
                }

                IconLabel {
                    Layout.fillWidth: true
                    iconSource: constant.faceLabelIcon
                    labelText:  qsTr("Face")
                }

                IconLabel {
                    Layout.fillWidth: true
                    iconSource: constant.settingsLabelIcon
                    labelText:  qsTr("Settings")
                    onClicked: {
                               __PushPage(BR.R.personalSettingsPage, {} );
                        // __PushPage(Qt.resolvedUrl("./Personal/SettingsPage.qml"), {} );
                    }
                }
            }
        }
    }
}



================================================
FILE: qml/WellChat/BussinessPage/ProfilePage.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

import Sparrow 1.0

import "../Component"

Page {
    id: profilePage
    title: qsTr("Profile") // 个人简介页面
    color: "#ebebeb"

    Constant {  id: constant  }

    focus: true
    Keys.onBackPressed: {
        event.accepted = true;
        try { stackView.pop(); }  catch(e) { }
    }

    topBar: TopBar {
        id: topBar
//        //! aviod looping binding
//        Item { anchors.fill: parent }
        RowLayout {
            anchors.fill: parent
            spacing: 10

            Item { width:  topBar.height - 2; height: width }

            SampleIcon {
                iconSource: constant.backActiveIcon
                height: topBar.height - 2
                width: topBar.height - 2
                anchors.verticalCenter: parent.verticalCenter
                onClicked: {
                    try { stackView.pop(); }  catch(e) { }
                }

                Separator {
                    color: "black"
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                }

                //! [0] fix the bug
                // 在本页面压入一个页面之后再弹出
                // x 的值会变成 180
                // 需要将其设置回 0
                onXChanged: {
                    if(x != 0 ) {
                        x = 0
                    }
                }
                //! [0] fix the bug
            }
        }
        // such as menuBar

        Row {
            parent: topBar
            anchors.left: parent.left
            anchors.leftMargin: (topBar.height - 2) * 1.5
            anchors.fill: parent
            SampleLabel {
                text: profilePage.title
                // Layout.alignment: Qt.AlignRight
                color: "white"
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }

    ScrollView {
        id: page
        anchors.fill: parent

        verticalScrollBarPolicy :Qt.ScrollBarAlwaysOff
        horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff

        Item {
            id: content
            width: page.width
            //width: Math.max(page.viewport.width, column.implicitWidth + 2 * column.spacing)
            height: Math.max(page.viewport.height, column.implicitHeight + 2 * column.spacing)

            ColumnLayout {
                id: column
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                spacing: 20

                Item {  width: parent.spacing;  height: parent.height }

                Rectangle {
                    Layout.fillWidth: true
                    height: rowLayout1.height + 10

                    RowLayout {
                        id: rowLayout1
                        width: parent.width
                        anchors.verticalCenter: parent.verticalCenter
                        spacing: 10

                        Item {  width: parent.spacing;  height: parent.height }

                        Image {
                            height: column1.height * 1.2
                            width: column1.height * 1.2
                            sourceSize: Qt.size(width, height)
                            source: constant.testPic
                        }

                        ColumnLayout {
                            id: column1
                            Layout.fillHeight: true
                            Row {
                                spacing: 10
                                SampleLabel {
                                    id: personName
                                    text: "小屁孩"
                                }
                                Image {
                                    height: personName.height
                                    width: personName.height
                                    sourceSize: Qt.size(width, height)
                                    source: constant.maleSampleIcon
                                }
                            }
                            SampleLabel {
                                id: showId
                                text: qsTr("ID: qyvlik")
                                color: "#888"
                            }
                            SampleLabel {
                                id: showNick
                                text: "昵称: qyvlik"
                                color: "#888"
                            }
                        }

                        Item { Layout.fillWidth: true }

                    } // rowLayout1
                } // colmnLayout1Parent

                Rectangle {
                    Layout.fillWidth: true
                    height: columnLayout2.height
                    color: "white"
                    ColumnLayout {
                        id: columnLayout2
                        width: parent.width
                        spacing: 0

                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("Region")
                            Label {
                                text: qsTr("Guangdong Shantou")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("What's Up")
                            Label {
                                text: "逝水流年"
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                font.family: GeneralSettings.generalfontFamily
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            // 相册
                            Layout.fillWidth: true
                            labelText:  qsTr("Album")

                            Row {
                                id: row1
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.right: parent.right
                                anchors.rightMargin: 10
                                height: parent.height
                                spacing: 5
                                Image {
                                    anchors.verticalCenter: parent.verticalCenter
                                    width: parent.height * 0.8
                                    height: parent.height * 0.8
                                    sourceSize: Qt.size(width, height)
                                    source: constant.testPic
                                }
                                Image {
                                    anchors.verticalCenter: parent.verticalCenter
                                    width: parent.height * 0.8
                                    height: parent.height * 0.8
                                    sourceSize: Qt.size(width, height)
                                    source: constant.testPic
                                }
                                Image {
                                    anchors.verticalCenter: parent.verticalCenter
                                    width: parent.height * 0.8
                                    height: parent.height * 0.8
                                    sourceSize: Qt.size(width, height)
                                    source: constant.testPic
                                }
                            }
                        }

                        Separator {
                            Layout.fillWidth: true; Layout.leftMargin: 10; Layout.rightMargin: 10
                            color: "#666"; orientation: Qt.Horizontal ;
                            anchors.horizontalCenter: parent.horizontalCenter
                        }

                        IconLabel {
                            Layout.fillWidth: true
                            labelText:  qsTr("From")
                            SampleLabel {
                                text: qsTr("Group Chat")
                                anchors.right: parent.right
                                anchors.verticalCenter: parent.verticalCenter
                                anchors.rightMargin: column.spacing
                                color: "#666"
                                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                            }
                        }
                    } // columnLayout2
                } // colmnLayout2Parent

                SampleButton {
                    text: "Message"
                    Layout.fillWidth: true
                    Layout.rightMargin: 50
                    Layout.leftMargin: 50
                    onClicked: {
                        // stackView.pop();
                        __PushPage(Qt.resolvedUrl("./Chat/ChatPage.qml"), {username: "小屁孩"});
                    }
                }

                SampleButton {
                    text: "Free Call"
                    Layout.fillWidth: true
                    Layout.rightMargin: 50
                    Layout.leftMargin: 50
                    onClicked: {
                    }
                }
            } // column
        } // content
    }// scrollview
}



================================================
FILE: qml/WellChat/BussinessPage/R.qml
================================================
// ~R

pragma Singleton
import QtQuick 2.0

// WellChat BussinessPage Resource
QtObject {
    id: resource

    objectName: "WellChatBussinessPageResource"

    readonly property
    url chatChatPage:
    Qt.resolvedUrl("./Chat/ChatPage.qml")

    readonly property
    url discoverMomentsPage:
    Qt.resolvedUrl("./Discover/MomentsPage/MomentsPage.qml")

    readonly property
    url personalSettingsAboutPage:
    Qt.resolvedUrl("./Personal/Settings/AboutPage.qml")

    readonly property
    url personalSettingsChatSettingsPage:
    Qt.resolvedUrl("./Personal/Settings/ChatSettingsPage.qml")

    readonly property
    url personalSettingsDoNotDisturbSettingsPage:
    Qt.resolvedUrl("./Personal/Settings/DoNotDisturbSettingsPage.qml")

    readonly property
    url personalSettingsGeneralSettingsPage:
    Qt.resolvedUrl("./Personal/Settings/GeneralSettingsPage.qml")

    readonly property
    url personalSettingsMyAccountSettingsPage:
    Qt.resolvedUrl("./Personal/Settings/MyAccountSettingsPage.qml")

    readonly property
    url personalSettingsNotificationsSettingsPage:
    Qt.resolvedUrl("./Personal/Settings/NotificationsSettingsPage.qml")

    readonly property
    url personalSettingsPrivacySettingsPage:
    Qt.resolvedUrl("./Personal/Settings/PrivacySettingsPage.qml")

    readonly property
    url personalFavoritesPage:
    Qt.resolvedUrl("./Personal/FavoritesPage.qml")

    readonly property
    url personalMyPostsPage:
    Qt.resolvedUrl("./Personal/MyPostsPage.qml")

    readonly property
    url personalSettingsPage:
    Qt.resolvedUrl("./Personal/SettingsPage.qml")

    readonly property
    url chatsView:
    Qt.resolvedUrl("./ChatsView.qml")

    readonly property
    url constactsView:
    Qt.resolvedUrl("./ContactsView.qml")

    readonly property
    url discoverPage:
    Qt.resolvedUrl("./DiscoverPage.qml")

    readonly property
    url profilePage:
    Qt.resolvedUrl("./ProfilePage.qml")

}



================================================
FILE: qml/WellChat/BussinessPage/qmldir
================================================
# this module is for this application
# don't use the other application

module BussinessPage

singleton R 1.0 ./R.qml


================================================
FILE: qml/WellChat/Component/+android/UI.js
================================================
// 这个文件用来适配UI 控件的
// 本文件是 安卓
.pragma library

// console.log("UI font point size", "android")

var smallFontPointSize = 12           // 主页面下的icon的文本例如chat等
var middleFontPointSize = 13
var normalFontPointSize = 20          // 文本编辑框,按钮中的字体大小
var bigFontPointSize = 36             // 软件标题


================================================
FILE: qml/WellChat/Component/Constant.qml
================================================
import QtQuick 2.0
import QtQuick.Window 2.2
import "./UI.js" as UI
import Sparrow 1.0

QtObject {
    id: constant
// "#71d01d":"#ccc"
    // 微信 深灰 #22292c
    // 微信绿 #71d01d
    // 普通灰 #ccc


    readonly property string fontFamily: GeneralSettings.generalfontFamily

    readonly property int smallFontPointSize : UI.smallFontPointSize          // 主页面下的icon的文本例如chat等
    readonly property int middleFontPointSize : UI.middleFontPointSize
    readonly property int normalFontPointSize : UI.normalFontPointSize        // 文本编辑框,按钮中的字体大小
    readonly property int bigFontPointSize : UI.bigFontPointSize              // 软件标题

    readonly property url testPic: Qt.resolvedUrl( "../Resource/tests/tests001.jpg")

    readonly property alias icons: __icons
    readonly property url iconsPath: "../Resource/icons/"

    readonly property url femaleSampleIcon: icons.sampleIcon("female")                      // 女性
    readonly property url maleSampleIcon: icons.sampleIcon("male")                          // 男性

    readonly property url soundActiveIcon: icons.activeIcon("sound")
    readonly property url soundInactiveIcon: icons.inactiveIcon("sound")
    readonly property url emoticonActiveIcon: icons.activeIcon("emoticon")
    readonly property url emoticonInactiveIcon: icons.inactiveIcon("emoticon")
    readonly property url backActiveIcon: icons.activeIcon("back")
    readonly property url backInactiveIcon: icons.inactiveIcon("back")
    readonly property url magnifierActiveIcon: icons.activeIcon("magnifier")
    readonly property url magnifierInactiveIcon: icons.inactiveIcon("magnifier")
    readonly property url plusActiveIcon: icons.activeIcon("plus")
    readonly property url plusInactiveIcon: icons.inactiveIcon("plus")
    readonly property url addActiveIcon: icons.activeIcon("a6c")
    readonly property url addInactiveIcon: icons.inactiveIcon("a6b")

    readonly property url momentsLabelIcon: icons.labelIcon("moments")                      // 朋友圈
    readonly property url scanQRCodeLabelIcon: icons.labelIcon("scan-qr-code")              // 二维码
    readonly property url shakeLabelIcon: icons.labelIcon("shake")                          // 摇一摇
    readonly property url peopleNearbyLabelIcon: icons.labelIcon("people-nearby")           // 附近的人
    readonly property url driftBottleLabelIcon: icons.labelIcon("drift-bottle")             // 漂流瓶
    readonly property url gamesLabelIcon: icons.labelIcon("games")                          // 游戏中心
    readonly property url favoritesLabelIcon: icons.labelIcon("favorites")                  // 收藏
    readonly property url myPostsLabelIcon: icons.labelIcon("my-posts")                     // 相册
    readonly property url settingsLabelIcon: icons.labelIcon("settings")                    // 设置
    readonly property url faceLabelIcon: icons.labelIcon("face")                            // 表情
    readonly property url walletLabelIcon: icons.labelIcon("wallet")                        // 钱包

    readonly property url shareExcelIcon: icons.share("share-excel")
    readonly property url shareFileIcon: icons.share("share-file")
    readonly property url shareMusicIcon: icons.share("share-music")
    readonly property url sharePdfIcon: icons.share("share-pdf")
    readonly property url sharePictureIcon: icons.share("share-picture")
    readonly property url sharePositionIcon: icons.share("share-position")
    readonly property url shareSoundIcon: icons.share("share-sound")
    readonly property url shareTextIcon: icons.share("share-text")
    readonly property url shareUrlIcon: icons.share("share-url")
    readonly property url shareVideoIcon: icons.share("share-video")
    readonly property url shareWordIcon: icons.share("share-word")
    readonly property url shareZipIcon: icons.share("share-zip")

    property var _icons: QtObject {
        id: __icons
        function share(name) {
            return Qt.resolvedUrl(iconsPath + "label-icons/" + name + ".png");
        }

        function labelIcon(name) {
            return Qt.resolvedUrl(iconsPath + "label-icons/" + name + ".png");
        }

        function activeIcon(name) {
            return Qt.resolvedUrl(iconsPath + "bar-icons/active/" + name +".png")
        }

        function inactiveIcon(name) {
            return Qt.resolvedUrl(iconsPath + "bar-icons/inactive/" + name +".png")
        }

        function sampleIcon(name) {
            return Qt.resolvedUrl(iconsPath + "icons/" + name +".png")
        }
    }

    //    property var _length: QtObject {
    //        id: __length
    //        readonly property int screenWidth: Screen.width
    //        readonly property int screenHeight: Screen.height
    //        readonly property real devicePixelRatio: Screen.devicePixelRatio
    //        readonly property real pixelDensity: Screen.pixelDensity

    //        function controlLength(l) {

    //        }

    //        /*!
    //           \internal
    //           This holds the pixel density used for converting millimeters into pixels. This is the exact
    //           value from \l Screen:pixelDensity, but that property only works from within a \l Window type,
    //           so this is hardcoded here and we update it from within \l ApplicationWindow
    //         */
    //        //         property real pixelDensity: 4.46
    //        property real multiplier: 1.4 //default multiplier, but can be changed by user

    //        /*!
    //           This is the standard function to use for accessing device-independent pixels. You should use
    //           this anywhere you need to refer to distances on the screen.
    //         */
    //        function dp(number) {
    //            return Math.round(number*((pixelDensity*25.4)/160)*multiplier);
    //        }

    //        function gu(number) {
    //            return number * gridUnit
    //        }

    //        property int gridUnit: dp(64)
    //    }

}


================================================
FILE: qml/WellChat/Component/Icon.qml
================================================
import QtQuick 2.5
import QtQuick.Layouts 1.1
import "./UI.js" as UI
import Sparrow 1.0

Rectangle {
    id: icon
    width: columnLayout.width
    height: columnLayout.height
    color: "transparent"

    signal clicked()

    property alias iconTextVisible: iconText.visible
    property size iconSize: Qt.size(33, 33)
    property alias iconText: iconText.text
    property alias activeIconOpacity: activeIconImage.opacity
    property alias activeIconSource: activeIconImage.source
    property alias inactiveIconSource: inactiveIconImage.source

    ColumnLayout {
        id: columnLayout
        anchors.centerIn: parent
        spacing: 0
        Item {
            width:  iconSize.width - iconText.height
            height: iconSize.height - iconText.height
            anchors.horizontalCenter: parent.horizontalCenter
            Image {
                id: activeIconImage
                anchors.fill: parent
                fillMode: Image.PreserveAspectFit
                opacity: 1
                Behavior on opacity {
                    NumberAnimation { duration: 300 }
                }
            }
            Image {
                id: inactiveIconImage
                anchors.centerIn: parent
                anchors.fill: parent
                fillMode: Image.PreserveAspectFit
                opacity: 1 - activeIconImage.opacity
            }
        }

        SampleLabel {
            id: iconText
            anchors.horizontalCenter: parent.horizontalCenter
            Layout.fillWidth: true
            verticalAlignment: Text.AlignBottom
            horizontalAlignment: Text.AlignHCenter
            font.pointSize: UI.smallFontPointSize
            color: activeIconImage.opacity == 0? "#999999": "#45c01a"
        }

        Item {
            height: iconText.contentHeight * 0.3
            width: iconText.contentHeight
        }

    }


    MouseArea {
        anchors.fill: parent
        onClicked: {
            icon.clicked();
        }
    }
}


================================================
FILE: qml/WellChat/Component/IconButton.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
// import "../"

Item {
    id: iconButton
    // Constant { id: constant }
    height: 40
    width: 40

    signal clicked()


    property bool active: false
    property url activeIconSource: ""
    property url inactiveIconSource: ""

    Accessible.role: Accessible.Button
    Accessible.name: "iconButton"
    Accessible.description: "shows the icon"
    Accessible.onPressAction: {
        // do a button click
        clicked()
    }

    Image {
        id: icon
        height: iconButton.height * 0.65
        width: iconButton.width * 0.65
        anchors.centerIn: parent
        fillMode: Image.PreserveAspectFit
        sourceSize: Qt.size(width, height)
        source: active ? activeIconSource : inactiveIconSource
    }

    MouseArea {
        anchors.fill: parent
        onClicked: iconButton.clicked()
        onPressed: {
            active = true;
        }

        onReleased: {
            active = false;
        }
    }
}


================================================
FILE: qml/WellChat/Component/IconLabel.qml
================================================
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import Sparrow 1.0

Rectangle {
    id: iconLabel

    color: "white"
    clip: true
    height: label.contentHeight * 3

    signal clicked()
    signal pressAndHold()

    property alias iconSource: icon.source
    property alias labelText: label.text
    property alias fontPointSize: label.font.pointSize
    property alias spacing: rowLayout.spacing

    RowLayout {
        id: rowLayout
        width: parent.width
        anchors.verticalCenter: parent.verticalCenter
        spacing: 20
        Item { width: parent.spacing; height: parent.spacing  }
        Image {
            id: icon
            height: label.contentHeight * 1.5
            width: label.contentHeight * 1.5
            sourceSize: Qt.size(width, height)
            visible: icon.status == Image.Ready
        }
        SampleLabel {
            id: label
        }
        Item { Layout.fillWidth: true }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: iconLabel.clicked();
        onPressed:  iconLabel.color = "#555";
        onReleased: iconLabel.color = "white";
        onPressAndHold: iconLabel.pressAndHold();
        onPositionChanged: iconLabel.color = "white";
    }
}


================================================
FILE: qml/WellChat/Component/MainListView.qml
================================================
import QtQuick 2.2

ListView {
    clip: true
    preferredHighlightBegin: 0
    preferredHighlightEnd: 0
    highlightMoveDuration: 250
    highlightRangeMode: ListView.StrictlyEnforceRange
    snapMode: ListView.SnapOneItem
    orientation: ListView.Horizontal
    maximumFlickVelocity: 3000
    boundsBehavior: ListView.StopAtBounds

    onCurrentIndexChanged: forceActiveFocus()
}


================================================
FILE: qml/WellChat/Component/SampleTextArea.qml
================================================
/*
 * author qyvlik
 * email qyvlik@qq.com
 * time 2015/4/10
 * FLatUI element FlatTextField
 *
*/
import QtQuick 2.5
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.4
import Sparrow 1.0

TextArea {
    id:textArea
    font.family: GeneralSettings.generalfontFamily
    font.pointSize: GeneralSettings.generalFontPointSize
    wrapMode: TextEdit.Wrap
    backgroundVisible: false
    // 微信绿 #71d01d
    // 普通灰 #ccc

//    style: TextAreaStyle {
//        renderType: Text.NativeRendering
//    }

    FontMetrics {
        id: fontMetrics
        font.family: GeneralSettings.generalfontFamily
        font.pointSize: GeneralSettings.generalFontPointSize
        font.weight: Font.Thin
        font.bold: false
    }

    Rectangle {
        width: parent.width - 10
        anchors.horizontalCenter: parent.horizontalCenter
        height: 1
        color: parent.focus? "#71d01d" : "#ccc"
        anchors.bottom: parent.bottom
        anchors.bottomMargin: fontMetrics.height * 0.2
    }
}


================================================
FILE: qml/WellChat/Component/ScrollBar.qml
================================================
import QtQuick 2.0

Item {
    id: scrollBar

    // The properties that define the scrollbar's state.
    // position and pageSize are in the range 0.0 - 1.0.  They are relative to the
    // height of the page, i.e. a pageSize of 0.5 means that you can see 50%
    // of the height of the view.
    // orientation can be either Qt.Vertical or Qt.Horizontal
    property real position
    property real pageSize
    property int orientation : Qt.Vertical

    // A light, semi-transparent background
    Rectangle {
        id: background
        anchors.fill: parent
        radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
        color: "white"
        opacity: 0.3
    }

    // Size the bar to the required size, depending upon the orientation.
    Rectangle {
        x: orientation == Qt.Vertical ? 1 : (scrollBar.position * (scrollBar.width-2) + 1)
        y: orientation == Qt.Vertical ? (scrollBar.position * (scrollBar.height-2) + 1) : 1
        width: orientation == Qt.Vertical ? (parent.width-2) : (scrollBar.pageSize * (scrollBar.width-2))
        height: orientation == Qt.Vertical ? (scrollBar.pageSize * (scrollBar.height-2)) : (parent.height-2)
        //radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
        color: "black"
        opacity: 0.7
    }
}


================================================
FILE: qml/WellChat/Component/Separator.qml
================================================
/*
 * author qyvlik
 * email qyvlik@qq.com
 * time 2015/4/10
 * FlatUI.Private element
 *
 * this qml file (element type) just for build module
 * not allow used by user
 *
 *
 * such as drow a line
*/

import QtQuick 2.0

Rectangle {
    id:separator
    property int orientation : Qt.Vertical // Qt.Horizontal
    property int length:orientation == Qt.Vertical ? parent.height*0.6 : parent.width*0.6
    property int separatorWidth : 1

    onOrientationChanged: __fix();
    onLengthChanged: __fix()
    onSeparatorWidthChanged: __fix()

    // private function
    function __fix(){
        switch(orientation){
        case Qt.Vertical:  // 垂直的
            height = length;
            width = separatorWidth;
            break;
        case Qt.Horizontal: // 水平的
            width = length;
            height = separatorWidth;
            break;
        default:
            height = length;
            width = separatorWidth;
            break;
        }
    }
    Component.onCompleted: __fix();
}



================================================
FILE: qml/WellChat/Component/UI.js
================================================
// 这个文件用来适配UI 控件的
// 本文件是win7
.pragma library

// console.log("UI font point size", "win7")

var smallFontPointSize = 8          // 主页面下的icon的文本例如chat等
var middleFontPointSize = 11
var normalFontPointSize = 14        // 文本编辑框,按钮中的字体大小
var bigFontPointSize = 18           // 软件标题


================================================
FILE: qml/WellChat/MainView.qml
================================================
import Resource 1.0 as Resource

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.4
import QtQml.Models 2.2

import Sparrow 1.0

import "./BussinessPage"  // has R.qml
import "./Component"

Page {
    id: mainView

    title: "WellChat"

    // Constant { }

    topBar: TopBar {
        id: topBar
        RowLayout {
            anchors.fill: parent
            // spacing: 20
            SampleLabel {
                Layout.leftMargin: 20
                text: title
                color: "white"
            }

            Item { Layout.fillWidth: true }

        }
        // such as menuBar
        Row {
            //! [0]
            parent: topBar
            anchors.right: parent.right
            anchors.rightMargin: 10
            //! [0]

            SampleIcon {
                iconSource: Resource.R.activeIconMagnifier
                id: iconButton2
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                onClicked: {
                    tryToNotify("我操!");
                }
            }

            SampleIcon {
                iconSource: Resource.R.activeIconPlus
                id: iconButton1
                iconSize: Qt.size( topBar.height - 2,  topBar.height - 2)
                onClicked: {
                    try {
                        console.log("try to setStatusBarColor",
                                    topBar.backgroundColor)
                        BridgingAndroid.setStatusBarColor(topBar.backgroundColor);
                    } catch(e){
                        console.log(e);
                    }
                }
            }
        }
    }

    bottomBar: BottomBar {
        id: bottomBar
        property  int iconHeight: topBar.height
        property  int iconWidth: topBar.width
        RowLayout {
            id: iconBar
            spacing: 0
            anchors.fill: parent
            readonly property var iconNames: ["Chat","Contacts","Discover", "Me"]
            function getActiveIconUrl(index) {
                return "./Resource/icons/bar-icons/active/"+iconNames[index].toLowerCase()+".png";
            }
            function getInctiveIconUrl(index) {
                return "./Resource/icons/bar-icons/inactive/"+iconNames[index].toLowerCase()+".png";
            }

            // Item { Layout.fillWidth: true }

            Repeater {
                id: repeater
                model:iconBar.iconNames
                Icon {
                    Layout.fillWidth: true
                    iconSize: Qt.size(topBar.height, topBar.height)
                    iconText: iconBar.iconNames[index]
                    activeIconSource: iconBar.getActiveIconUrl(index)
                    inactiveIconSource: iconBar.getInctiveIconUrl(index)
                    activeIconOpacity: (mainListView.currentIndex == index)
                    onClicked: {
                        mainListView.currentIndex = index;
                        mainListView.currentItem.focus = true;
                    }
                }
            }
        }
    }

    MainListView {
        id: mainListView
        focus: mainView.focus
        anchors.fill: parent
        model: itemsModel
    }

    ObjectModel {
        id: itemsModel

        ChatsView {
            id: chatsView
            pageStackWindow: mainView.pageStackWindow
            stackView: mainView.stackView
            width: mainListView.width
            height: mainListView.height
        }

        ContactsView {
            id: contactsView
            mainListView: mainListView
            pageStackWindow: ma
Download .txt
gitextract_f1fzdbi7/

├── .gitignore
├── LICENSE
├── README.md
├── Sparrow/
│   ├── Sparrow.pri
│   ├── keyboard.cpp
│   ├── keyboard.h
│   ├── qmlnetworkaccessmanagerfactory.cpp
│   ├── qmlnetworkaccessmanagerfactory.h
│   ├── qtbridgingandroid.cpp
│   ├── qtbridgingandroid.h
│   └── sparrow_global.h
├── WellChat.pro
├── android/
│   ├── AndroidManifest.xml
│   ├── assets/
│   │   └── font/
│   │       └── NotoSansHans-DemiLight.otf
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── res/
│   │   └── values/
│   │       └── libs.xml
│   └── src/
│       └── org/
│           └── gdpurjyfs/
│               ├── sparrow/
│               │   └── QtBridgingAndroid.java
│               └── wellchat/
│                   └── WellChatActivity.java
├── deployment.pri
├── desktop.qrc
├── doc/
│   └── weixin-ui-analyse.md
├── main.cpp
├── qml/
│   └── WellChat/
│       ├── BussinessPage/
│       │   ├── Chat/
│       │   │   ├── ChatPage.qml
│       │   │   ├── Heartbeat.qml
│       │   │   ├── Lazy.qml
│       │   │   ├── Tuling123.js
│       │   │   └── heart.js
│       │   ├── ChatsView.qml
│       │   ├── Contacts/
│       │   │   └── ContactsListView.qml
│       │   ├── ContactsView.qml
│       │   ├── Discover/
│       │   │   └── MomentsPage/
│       │   │       └── MomentsPage.qml
│       │   ├── DiscoverPage.qml
│       │   ├── Personal/
│       │   │   ├── FavoritesPage.qml
│       │   │   ├── MyPostsPage.qml
│       │   │   ├── Settings/
│       │   │   │   ├── AboutPage.qml
│       │   │   │   ├── ChatSettingsPage.qml
│       │   │   │   ├── DoNotDisturbSettingsPage.qml
│       │   │   │   ├── GeneralSettingsPage.qml
│       │   │   │   ├── MyAccountSettingsPage.qml
│       │   │   │   ├── NotificationsSettingsPage.qml
│       │   │   │   ├── PrivacySettingsPage.qml
│       │   │   │   └── SettingsGroup.qml
│       │   │   └── SettingsPage.qml
│       │   ├── PersonalPage.qml
│       │   ├── ProfilePage.qml
│       │   ├── R.qml
│       │   └── qmldir
│       ├── Component/
│       │   ├── +android/
│       │   │   └── UI.js
│       │   ├── Constant.qml
│       │   ├── Icon.qml
│       │   ├── IconButton.qml
│       │   ├── IconLabel.qml
│       │   ├── MainListView.qml
│       │   ├── SampleTextArea.qml
│       │   ├── ScrollBar.qml
│       │   ├── Separator.qml
│       │   └── UI.js
│       ├── MainView.qml
│       ├── Sparrow/
│       │   ├── +android/
│       │   │   ├── UI.js
│       │   │   └── WebPage.qml
│       │   ├── BottomBar.qml
│       │   ├── ClickedShaderEffect.qml
│       │   ├── GeneralSettings.qml
│       │   ├── Page.qml
│       │   ├── PageStackWindow.qml
│       │   ├── PopupLayer/
│       │   │   ├── Delegate/
│       │   │   │   ├── PopupLayerBottomMenuDelegate.qml
│       │   │   │   ├── PopupLayerDialogDelegate.qml
│       │   │   │   ├── PopupLayerSideMenuDelegate.qml
│       │   │   │   └── qmldir
│       │   │   ├── PopupLayer.qml
│       │   │   ├── PopupLayerDelegate.qml
│       │   │   ├── PopupLayerTransition.qml
│       │   │   ├── qmldir
│       │   │   └── readme.md
│       │   ├── QObject.qml
│       │   ├── SampleButton.qml
│       │   ├── SampleIcon.qml
│       │   ├── SampleLabel.qml
│       │   ├── SampleTextField.qml
│       │   ├── TopBar.qml
│       │   ├── Tracker.qml
│       │   ├── UI.js
│       │   ├── WebPage.qml
│       │   ├── qmldir
│       │   └── resources/
│       │       ├── NotoSansHans-DemiLight.otf
│       │       └── readme.md
│       ├── WellChat.qmlproject
│       ├── main.qml
│       └── resource/
│           ├── R.qml
│           └── qmldir
├── qml.qrc
└── src/
    └── wellchat/
        ├── collectionsmodel.cpp
        └── collectionsmodel.h
Download .txt
SYMBOL INDEX (26 symbols across 11 files)

FILE: Sparrow/keyboard.cpp
  function QRectF (line 33) | QRectF Keyboard::keyboardRectangle() const
  function Keyboard (line 38) | Keyboard *Keyboard::singleton()

FILE: Sparrow/keyboard.h
  function class (line 11) | class Keyboard : public QObject

FILE: Sparrow/qmlnetworkaccessmanagerfactory.cpp
  function QNetworkAccessManager (line 23) | QNetworkAccessManager *QmlNetworkAccessManagerFactory::create(QObject *p...

FILE: Sparrow/qmlnetworkaccessmanagerfactory.h
  function class (line 6) | class QmlNetworkAccessManagerFactory : public QQmlNetworkAccessManagerFa...

FILE: Sparrow/qtbridgingandroid.h
  function class (line 8) | class QtBridgingAndroid : public QObject

FILE: android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java
  class SetStatusBarColorRunnable (line 51) | class SetStatusBarColorRunnable implements Runnable
    method SetStatusBarColorRunnable (line 55) | public SetStatusBarColorRunnable(Activity activity, int color) {
    method run (line 60) | @Override
  class QtBridgingAndroid (line 66) | public class QtBridgingAndroid
    method setStatusBarColor (line 80) | public static void setStatusBarColor(String colorString) {
    method notify (line 97) | public static void notify(String notifyText)
    method getRootView (line 111) | private static View getRootView(Activity context)
    method listenKeyboardHeight (line 118) | public static void listenKeyboardHeight() {
    method notifiedKeyboardRectangle (line 160) | public static native void notifiedKeyboardRectangle(int x, int y,
    method Init (line 164) | public static void Init(Activity instanceActivity) {

FILE: android/src/org/gdpurjyfs/wellchat/WellChatActivity.java
  class WellChatActivity (line 53) | public class WellChatActivity extends org.qtproject.qt5.android.bindings...
    method WellChatActivity (line 62) | public WellChatActivity()

FILE: main.cpp
  function main (line 18) | int main(int argc, char *argv[])

FILE: qml/WellChat/BussinessPage/Chat/Tuling123.js
  function sendTextToTuling123 (line 5) | function sendTextToTuling123(text, chatUserId, callback, err) {
  function isErrorCode (line 40) | function isErrorCode(code) {
  function errorCodeHandle (line 79) | function errorCodeHandle(code) {

FILE: src/wellchat/collectionsmodel.cpp
  function QString (line 85) | QString CollectionsModel::roleName(int role) {
  function QVariant (line 138) | QVariant CollectionsModel::data(const QModelIndex &index, int role) const
  function QObject (line 196) | QObject *CollectionsModel::singleton(QQmlEngine *qmlEngine, QJSEngine *j...

FILE: src/wellchat/collectionsmodel.h
  function Q_OBJECT (line 12) | Q_OBJECT
Condensed preview — 97 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (276K chars).
[
  {
    "path": ".gitignore",
    "chars": 24,
    "preview": "WellChat.pro.user\n*.user"
  },
  {
    "path": "LICENSE",
    "chars": 1077,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 GDPURJYFS\n\nPermission is hereby granted, free of charge, to any person obtaini"
  },
  {
    "path": "README.md",
    "chars": 1240,
    "preview": "# WellChat\n\nWellChat is a Application that is a WeChat-like APP by qml.\n\n> best tool vesion:\n\n> Qt version >= 5.5.0\n\n> A"
  },
  {
    "path": "Sparrow/Sparrow.pri",
    "chars": 635,
    "preview": "QT += core network sql qml\n\nandroid {\n    QT += androidextras\n\n}\n\nHEADERS += \\\n    #$$PWD/qmlnetworkaccessmanagerfactory"
  },
  {
    "path": "Sparrow/keyboard.cpp",
    "chars": 1246,
    "preview": "#include \"keyboard.h\"\n#include <QGuiApplication>\n#include <QInputMethod>\n\n#include \"sparrow_global.h\"\n\nKeyboard::Keyboar"
  },
  {
    "path": "Sparrow/keyboard.h",
    "chars": 987,
    "preview": "#ifndef VIRTUALKEYBOARD_H\n#define VIRTUALKEYBOARD_H\n\n#include <QObject>\n#include <QRectF>\n\nclass QtBridgingAndroid;\nclas"
  },
  {
    "path": "Sparrow/qmlnetworkaccessmanagerfactory.cpp",
    "chars": 1007,
    "preview": "#include \"qmlnetworkaccessmanagerfactory.h\"\n\n#include <QDir>\n#include <QDebug>\n#include <QNetworkAccessManager>\n#include"
  },
  {
    "path": "Sparrow/qmlnetworkaccessmanagerfactory.h",
    "chars": 391,
    "preview": "#ifndef QMLNETWORKACCESSMANAGERFACTORY_H\n#define QMLNETWORKACCESSMANAGERFACTORY_H\n\n#include <QQmlNetworkAccessManagerFac"
  },
  {
    "path": "Sparrow/qtbridgingandroid.cpp",
    "chars": 4146,
    "preview": "#include \"qtbridgingandroid.h\"\n#include \"keyboard.h\"\n#include <QRect>\n#include <QRectF>\n#include <QGuiApplication>\n\nQtBr"
  },
  {
    "path": "Sparrow/qtbridgingandroid.h",
    "chars": 700,
    "preview": "#ifndef QTBRIDGINGANDROID_H\n#define QTBRIDGINGANDROID_H\n\n#include <QObject>\n#include <QColor>\n#include \"sparrow_global.h"
  },
  {
    "path": "Sparrow/sparrow_global.h",
    "chars": 475,
    "preview": "#ifndef GLOBAL\n#define GLOBAL\n\n#include <QDebug>\n\n#ifdef Q_OS_ANDROID\n\n#include <QtAndroidExtras/QAndroidJniObject>\n#inc"
  },
  {
    "path": "WellChat.pro",
    "chars": 804,
    "preview": "TEMPLATE = app\n\nQT += qml quick widgets\n\nSOURCES += main.cpp \\\n    src/wellchat/collectionsmodel.cpp\n\nRESOURCES += \\\n   "
  },
  {
    "path": "android/AndroidManifest.xml",
    "chars": 4328,
    "preview": "<?xml version=\"1.0\"?>\n<manifest package=\"org.gdpurjyfs.wellchat\" xmlns:android=\"http://schemas.android.com/apk/res/andro"
  },
  {
    "path": "android/build.gradle",
    "chars": 1502,
    "preview": "buildscript {\n    repositories {\n        jcenter()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:"
  },
  {
    "path": "android/gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Wed Apr 10 15:27:10 PDT 2013\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "android/gradlew",
    "chars": 5080,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "android/gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "android/res/values/libs.xml",
    "chars": 661,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<resources>\n    <array name=\"qt_sources\">\n        <item>https://download.qt-proje"
  },
  {
    "path": "android/src/org/gdpurjyfs/sparrow/QtBridgingAndroid.java",
    "chars": 6575,
    "preview": "/*\n * Copyright (c) <2015> <copyright qyvlik>\n *\n * Permission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "android/src/org/gdpurjyfs/wellchat/WellChatActivity.java",
    "chars": 2490,
    "preview": "/****************************************************************************\n**\n** Copyright (C) 2015 The Qt Company Lt"
  },
  {
    "path": "deployment.pri",
    "chars": 648,
    "preview": "android-no-sdk {\n    target.path = /data/user/qt\n    export(target.path)\n    INSTALLS += target\n} else:android {\n    QT "
  },
  {
    "path": "desktop.qrc",
    "chars": 136,
    "preview": "<RCC>\n    <qresource prefix=\"/\">\n        <file>qml/WellChat/Sparrow/resources/NotoSansHans-DemiLight.otf</file>\n    </qr"
  },
  {
    "path": "doc/weixin-ui-analyse.md",
    "chars": 1577,
    "preview": "# 微信界面剖析\n\n微信界面剖析分为:首界面,单个界面,字体大小,素材等。\n\n## 首界面\n\n可以先查看[简单易用的页面栈框架](readme.md)。\n\n先看看微信的首界面。有四个分页,`BottomBar` 可以显示当前页面的以及进行切"
  },
  {
    "path": "main.cpp",
    "chars": 1984,
    "preview": "/*!\n * Activity 先于 Qt 加载\n * 1. 在 Activity OnCreate 中调用 QtBridgingAndroid::Init,然后进入Qt::main\n * 2. 在 Qt::main 中注册 Java 的 "
  },
  {
    "path": "qml/WellChat/BussinessPage/Chat/ChatPage.qml",
    "chars": 16101,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick.Layout"
  },
  {
    "path": "qml/WellChat/BussinessPage/Chat/Heartbeat.qml",
    "chars": 713,
    "preview": "import QtQuick 2.0\n\nQtObject {\n    id: heartbeat\n\n    property alias source: worker.source\n    property alias interval: "
  },
  {
    "path": "qml/WellChat/BussinessPage/Chat/Lazy.qml",
    "chars": 648,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick.Layout"
  },
  {
    "path": "qml/WellChat/BussinessPage/Chat/Tuling123.js",
    "chars": 3252,
    "preview": ".pragma library\n\n// callback(responseText)\n// err(errorCode)\nfunction sendTextToTuling123(text, chatUserId, callback, er"
  },
  {
    "path": "qml/WellChat/BussinessPage/Chat/heart.js",
    "chars": 1294,
    "preview": "// .pragma library\n\n// 心跳包\n\n// to include static singleton mess_id\nQt.include(\"./storage.js\")\n\nWorkerScript.onMessage = "
  },
  {
    "path": "qml/WellChat/BussinessPage/ChatsView.qml",
    "chars": 9745,
    "preview": "\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick"
  },
  {
    "path": "qml/WellChat/BussinessPage/Contacts/ContactsListView.qml",
    "chars": 3791,
    "preview": "import QtQuick 2.5\nimport QtQuick.Window 2.0\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0 as Sparrow\n\nRectangle {\n    i"
  },
  {
    "path": "qml/WellChat/BussinessPage/ContactsView.qml",
    "chars": 2933,
    "preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
  },
  {
    "path": "qml/WellChat/BussinessPage/Discover/MomentsPage/MomentsPage.qml",
    "chars": 2813,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.2\nimport QtQuick.Layout"
  },
  {
    "path": "qml/WellChat/BussinessPage/DiscoverPage.qml",
    "chars": 4550,
    "preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/FavoritesPage.qml",
    "chars": 3333,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Layouts 1.1\n\nimport \"../../Component\"\nimport \"./Settings\"\n\ni"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/MyPostsPage.qml",
    "chars": 3336,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport \"../../Compo"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/AboutPage.qml",
    "chars": 5690,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/ChatSettingsPage.qml",
    "chars": 5548,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/DoNotDisturbSettingsPage.qml",
    "chars": 5880,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/GeneralSettingsPage.qml",
    "chars": 10201,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/MyAccountSettingsPage.qml",
    "chars": 8885,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/NotificationsSettingsPage.qml",
    "chars": 7994,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/PrivacySettingsPage.qml",
    "chars": 9122,
    "preview": "import Resource 1.0 as R\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/Settings/SettingsGroup.qml",
    "chars": 1306,
    "preview": "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nimport QtQuick.Controls 1.4\nimport \"../../../Component\"\nimport Sparrow 1.0"
  },
  {
    "path": "qml/WellChat/BussinessPage/Personal/SettingsPage.qml",
    "chars": 7239,
    "preview": "import Resource 1.0 as R\nimport BussinessPage 1.0 as BR\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.L"
  },
  {
    "path": "qml/WellChat/BussinessPage/PersonalPage.qml",
    "chars": 5895,
    "preview": "import BussinessPage 1.0 as BR\n\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Window 2.0\nimport QtQuick."
  },
  {
    "path": "qml/WellChat/BussinessPage/ProfilePage.qml",
    "chars": 10621,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\n\nimport Sparrow 1.0\n\nimport \"../Component\"\n\nPa"
  },
  {
    "path": "qml/WellChat/BussinessPage/R.qml",
    "chars": 1944,
    "preview": "// ~R\n\npragma Singleton\nimport QtQuick 2.0\n\n// WellChat BussinessPage Resource\nQtObject {\n    id: resource\n\n    objectNa"
  },
  {
    "path": "qml/WellChat/BussinessPage/qmldir",
    "chars": 119,
    "preview": "# this module is for this application\n# don't use the other application\n\nmodule BussinessPage\n\nsingleton R 1.0 ./R.qml\n"
  },
  {
    "path": "qml/WellChat/Component/+android/UI.js",
    "chars": 287,
    "preview": "// 这个文件用来适配UI 控件的\n// 本文件是 安卓\n.pragma library\n\n// console.log(\"UI font point size\", \"android\")\n\nvar smallFontPointSize = "
  },
  {
    "path": "qml/WellChat/Component/Constant.qml",
    "chars": 5919,
    "preview": "import QtQuick 2.0\nimport QtQuick.Window 2.2\nimport \"./UI.js\" as UI\nimport Sparrow 1.0\n\nQtObject {\n    id: constant\n// \""
  },
  {
    "path": "qml/WellChat/Component/Icon.qml",
    "chars": 2000,
    "preview": "import QtQuick 2.5\nimport QtQuick.Layouts 1.1\nimport \"./UI.js\" as UI\nimport Sparrow 1.0\n\nRectangle {\n    id: icon\n    wi"
  },
  {
    "path": "qml/WellChat/Component/IconButton.qml",
    "chars": 1000,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\n// import \"../\"\n\nItem {\n    id: iconButton\n    // Constant { id: constant"
  },
  {
    "path": "qml/WellChat/Component/IconLabel.qml",
    "chars": 1258,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0\n\nRectangle {\n    id: iconLa"
  },
  {
    "path": "qml/WellChat/Component/MainListView.qml",
    "chars": 385,
    "preview": "import QtQuick 2.2\n\nListView {\n    clip: true\n    preferredHighlightBegin: 0\n    preferredHighlightEnd: 0\n    highlightM"
  },
  {
    "path": "qml/WellChat/Component/SampleTextArea.qml",
    "chars": 1005,
    "preview": "/*\n * author qyvlik\n * email qyvlik@qq.com\n * time 2015/4/10\n * FLatUI element FlatTextField\n *\n*/\nimport QtQuick 2.5\nim"
  },
  {
    "path": "qml/WellChat/Component/ScrollBar.qml",
    "chars": 1314,
    "preview": "import QtQuick 2.0\n\nItem {\n    id: scrollBar\n\n    // The properties that define the scrollbar's state.\n    // position a"
  },
  {
    "path": "qml/WellChat/Component/Separator.qml",
    "chars": 1009,
    "preview": "/*\n * author qyvlik\n * email qyvlik@qq.com\n * time 2015/4/10\n * FlatUI.Private element\n *\n * this qml file (element type"
  },
  {
    "path": "qml/WellChat/Component/UI.js",
    "chars": 279,
    "preview": "// 这个文件用来适配UI 控件的\n// 本文件是win7\n.pragma library\n\n// console.log(\"UI font point size\", \"win7\")\n\nvar smallFontPointSize = 8 "
  },
  {
    "path": "qml/WellChat/MainView.qml",
    "chars": 4531,
    "preview": "import Resource 1.0 as Resource\n\nimport QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\nimport QtQuic"
  },
  {
    "path": "qml/WellChat/Sparrow/+android/UI.js",
    "chars": 1798,
    "preview": ".pragma library\n\n// console.log(\"Android UI Config\");\n\nvar defaultFontFamily = \"Noto Sans Hanunoo\";\n//var defaultNormalF"
  },
  {
    "path": "qml/WellChat/Sparrow/+android/WebPage.qml",
    "chars": 1096,
    "preview": "// just for android\nimport QtWebView 1.0\n\nimport QtQuick 2.0\nimport Sparrow 1.0\n\n/*\ncanGoBack : bool\ncanGoForward : bool"
  },
  {
    "path": "qml/WellChat/Sparrow/BottomBar.qml",
    "chars": 504,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport QtQuick.Controls.Styles 1.2\n\nStatusBar {\n    id: statusBar\n\n    pr"
  },
  {
    "path": "qml/WellChat/Sparrow/ClickedShaderEffect.qml",
    "chars": 3232,
    "preview": "import QtQuick 2.5\nimport QtGraphicalEffects 1.0\n\nShaderEffect {\n    id: shaderEffect\n\n    // signal clicked();\n    \n   "
  },
  {
    "path": "qml/WellChat/Sparrow/GeneralSettings.qml",
    "chars": 1947,
    "preview": "pragma Singleton\n\nimport QtQuick 2.0\n// import Qt.labs.settings 1.0\nimport \"UI.js\" as UI\n\nQObject {\n    id: generalSetti"
  },
  {
    "path": "qml/WellChat/Sparrow/Page.qml",
    "chars": 8834,
    "preview": "import QtQuick 2.4\nimport QtQuick.Controls 1.2\nimport Sparrow 1.0\n\nRectangle {\n    id: page\n\n    width: 360\n    height: "
  },
  {
    "path": "qml/WellChat/Sparrow/PageStackWindow.qml",
    "chars": 1165,
    "preview": "import QtQuick 2.0\nimport QtQuick.Layouts 1.1\nimport QtQuick.Controls 1.2\nimport QtQuick.Controls.Styles 1.3\n\nApplicatio"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerBottomMenuDelegate.qml",
    "chars": 1398,
    "preview": "//~ PopupLayerDialogDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopupLa"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerDialogDelegate.qml",
    "chars": 2226,
    "preview": "//~ PopupLayerDialogDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopupLa"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/Delegate/PopupLayerSideMenuDelegate.qml",
    "chars": 1397,
    "preview": "//~ PopupLayerSideMenuDelegate\n\n// internal import\n// don't use the module import\nimport \"../\"\nimport QtQuick 2.0\n\nPopup"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/Delegate/qmldir",
    "chars": 220,
    "preview": "module PopupLayer.Delegate\n\nPopupLayerDialogDelegate 1.0 ./PopupLayerDialogDelegate.qml\nPopupLayerSideMenuDelegate 1.0 ."
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/PopupLayer.qml",
    "chars": 2029,
    "preview": "//! Qt 5.0 or new\n\n// internal import\n// don't use the module import\nimport \"./Delegate\" as Delegate\nimport QtQuick 2.0\n"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/PopupLayerDelegate.qml",
    "chars": 348,
    "preview": "//~ PopupLayerDelegate\nimport QtQuick 2.0\n\nQtObject {\n    id: popupLayerDelegate\n\n    property PopupLayerTransition show"
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/PopupLayerTransition.qml",
    "chars": 259,
    "preview": "import QtQuick 2.0\n\nQtObject {\n    id: popupLayerTransition\n    default property alias animaitons: popupLayerTransition."
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/qmldir",
    "chars": 151,
    "preview": "module PopupLayer\n\nPopupLayer 1.0 ./PopupLayer.qml\nPopupLayerDelegate 1.0 ./PopupLayerDelegate.qml\nPopupLayerTransition "
  },
  {
    "path": "qml/WellChat/Sparrow/PopupLayer/readme.md",
    "chars": 3581,
    "preview": "# PopupLayer\n\n使用 QML 实现的弹出层。\n\n使用注意事项。\n\n1. `PopupLayer` 内部有个 `popupItem`,是作为这个控件内部孩子的默认父指针。\n\n2. `PopupLayer` 默认覆盖他的 `pare"
  },
  {
    "path": "qml/WellChat/Sparrow/QObject.qml",
    "chars": 132,
    "preview": "import QtQuick 2.0\n\nQtObject {\n    id: qObject\n    default property alias data: qObject.__data\n    property list<QtObjec"
  },
  {
    "path": "qml/WellChat/Sparrow/SampleButton.qml",
    "chars": 1646,
    "preview": "import QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\nimport QtGraphicalEffects 1.0\nimport S"
  },
  {
    "path": "qml/WellChat/Sparrow/SampleIcon.qml",
    "chars": 969,
    "preview": "import QtQuick 2.5\nimport QtQuick.Layouts 1.1\nimport Sparrow 1.0\n\nItem {\n    id: icon\n\n    property alias backgroundColo"
  },
  {
    "path": "qml/WellChat/Sparrow/SampleLabel.qml",
    "chars": 185,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport Sparrow 1.0\n\nLabel {\n    font.family: GeneralSettings.generalfontF"
  },
  {
    "path": "qml/WellChat/Sparrow/SampleTextField.qml",
    "chars": 982,
    "preview": "import Sparrow 1.0\nimport QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\n\nTextField {\n    id"
  },
  {
    "path": "qml/WellChat/Sparrow/TopBar.qml",
    "chars": 1608,
    "preview": "import QtQuick 2.5\nimport QtQuick.Controls 1.4\nimport QtQuick.Controls.Styles 1.4\nimport QtQuick.Layouts 1.1\n\nToolBar {\n"
  },
  {
    "path": "qml/WellChat/Sparrow/Tracker.qml",
    "chars": 173,
    "preview": "import QtQuick 2.0\n\nRectangle {\n    anchors.fill: parent\n    color: \"green\"\n    opacity: 0.5\n//    color: \"transparent\"\n"
  },
  {
    "path": "qml/WellChat/Sparrow/UI.js",
    "chars": 352,
    "preview": ".pragma library\n\n// console.log(\"Window UI Config\");\n\nvar defaultFontFamily = \"Microsoft YaHei UI\"; // 微软雅黑\n//var defaul"
  },
  {
    "path": "qml/WellChat/Sparrow/WebPage.qml",
    "chars": 1167,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.2\nimport QtWebKit 3.0\nimport Sparrow 1.0\n\n/*\ncanGoBack : bool\ncanGoForward "
  },
  {
    "path": "qml/WellChat/Sparrow/qmldir",
    "chars": 525,
    "preview": "# version 1.0\nmodule Sparrow\n\nUI 1.0 ./UI.js\nsingleton GeneralSettings 1.0 ./GeneralSettings.qml\n\nQObject 1.0 ./QObject."
  },
  {
    "path": "qml/WellChat/Sparrow/resources/readme.md",
    "chars": 80,
    "preview": "在安卓中,推荐字体需要大家来进行测试了。。。\n\n[有哪些值得推荐的中文字体?](https://www.zhihu.com/question/20727176)"
  },
  {
    "path": "qml/WellChat/WellChat.qmlproject",
    "chars": 707,
    "preview": "import QmlProject 1.0\n\nProject {\n    /* Include .qml, .js, and image files from current directory and subdirectories */\n"
  },
  {
    "path": "qml/WellChat/main.qml",
    "chars": 1031,
    "preview": "import QtQuick 2.0\nimport QtQuick.Controls 1.4\nimport Sparrow 1.0\n\nPageStackWindow {\n    id: mainWindow\n\n    title: qsTr"
  },
  {
    "path": "qml/WellChat/resource/R.qml",
    "chars": 4680,
    "preview": "pragma Singleton\n\nimport QtQuick 2.0\n\n// R\n// Applicaton icon html ... resource\n\nQtObject {\n    id: resource\n\n    object"
  },
  {
    "path": "qml/WellChat/resource/qmldir",
    "chars": 41,
    "preview": "module Resource\n\nsingleton R 1.0 ./R.qml\n"
  },
  {
    "path": "qml.qrc",
    "chars": 10426,
    "preview": "<RCC>\n    <qresource prefix=\"/\">\n        <file>qml/WellChat/BussinessPage/Chat/ChatPage.qml</file>\n        <file>qml/Wel"
  },
  {
    "path": "src/wellchat/collectionsmodel.cpp",
    "chars": 6589,
    "preview": "#include \"collectionsmodel.h\"\n#include <QSqlQuery>\n#include <QDebug>\n#include <QSqlError>\n#include <QStandardPaths>\n#inc"
  },
  {
    "path": "src/wellchat/collectionsmodel.h",
    "chars": 1055,
    "preview": "#ifndef COLLECTIONSMODEL_H\n#define COLLECTIONSMODEL_H\n\n#include <QAbstractListModel>\n#include <QSqlDatabase>\n\nclass QQml"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the GDPURJYFS/WellChat GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 97 files (248.8 KB), approximately 57.0k tokens, and a symbol index with 26 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!