Commit cbff9eac authored by Karel Slaný's avatar Karel Slaný

Merge branch 'send-msg-prototype' into 'develop'

Basic support for send message

See merge request !75
parents df31ea63 458700b1
......@@ -84,6 +84,7 @@ TRANSLATIONS_FILES += \
SOURCES += \
src/accounts.cpp \
src/auxiliaries/attachment_helper.cpp \
src/dialogues/dialogues.cpp \
src/dialogues/qml_dialogue_helper.cpp \
src/dialogues/qml_input_dialogue.cpp \
......@@ -133,11 +134,13 @@ SOURCES += \
src/worker/task_find_databox.cpp \
src/worker/task_find_databox_fulltext.cpp \
src/worker/task_keep_alive.cpp \
src/worker/task_send_message.cpp \
src/worker/task_send_sms.cpp \
src/zfo.cpp
HEADERS += \
src/accounts.h \
src/auxiliaries/attachment_helper.h \
src/common.h \
src/dialogues/dialogues.h \
src/dialogues/qml_dialogue_helper.h \
......@@ -188,6 +191,7 @@ HEADERS += \
src/worker/task_find_databox.h \
src/worker/task_find_databox_fulltext.h \
src/worker/task_keep_alive.h \
src/worker/task_send_message.h \
src/worker/task_send_sms.h \
src/zfo.h
......
......@@ -26,23 +26,34 @@ import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import cz.nic.mobileDatovka.modelEntries 1.0
ListView {
id: root
/* These signals should be captured to implement databox interaction. */
signal dbClicked(string dbID, string dbType, string dbName, string dbAddress, string dbEffectiveOvm)
/* These properties must be set by caller. */
property bool canDetailBoxes: false // enables viewing of box details
property bool canSelectBoxes: false // enables selecting of entries
property bool canDeselectBoxes: false // enables deselecting of entries
property bool canRemoveBoxes: false // enables removing of entries
/* This signal should be captured to implement model interaction. */
signal boxDetail(string boxId)
signal boxSelect(string boxId)
signal boxDeselect(string boxId)
signal boxRemove(string boxId)
delegate: Rectangle {
id: dbItem
height: listItemHeight
width: parent.width
color: datovkaPalette.base
color: rDbSelected ? readBgColor : datovkaPalette.base
Item {
id: databoxData
anchors.fill: parent
anchors.margins: defaultMargin
GridLayout {
id: grid
id: gridSearchDatabox
columns: 2
rows: 3
rowSpacing: defaultMargin * 0.6
......@@ -75,7 +86,7 @@ ListView {
Text {
id: r3c2
font.pointSize: textFontSizeSmall
text: (rDbIc == "") ? rDbIc : "IČ:" + rDbIc
text: (rDbIc == "") ? rDbIc : "IČ: " + rDbIc
}
Text {
id: hiddenText
......@@ -83,8 +94,22 @@ ListView {
font.pointSize: textFontSizeSmall
text: rDbEffectiveOvm
}
}
} // GridLayout
} // Item
MouseArea {
anchors.fill: parent
onClicked: {
if (canDetailBoxes && !(canSelectBoxes || canDeselectBoxes)) {
root.boxDetail(rDbID)
} else if (!canDetailBoxes && (canSelectBoxes || canDeselectBoxes)) {
if (rDbSelected && canDeselectBoxes) {
root.boxDeselect(rDbID)
} else if (!rDbSelected && canSelectBoxes) {
root.boxSelect(rDbID)
}
}
}
}
Rectangle {
id: next
anchors.verticalCenter: parent.verticalCenter
......@@ -97,21 +122,41 @@ ListView {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: defaultMargin
sourceSize.height: navImgHeight
source: "qrc:/ui/next.svg"
}
sourceSize.height: canDetailBoxes ? navImgHeight : imgHeight
source: {
// set icon based on the databox list operation
if (canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && !canRemoveBoxes) {
// we can view data box detail only
"qrc:/ui/next.svg"
} else if (!canDetailBoxes && (canSelectBoxes || canDeselectBoxes) && !canRemoveBoxes) {
if (rDbSelected && canDeselectBoxes) {
"qrc:/ui/subtract.svg"
} else if (!rDbSelected && canSelectBoxes) {
"qrc:/ui/add.svg"
}
} else if (!canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes) {
// we can remove data box from send message recipient list
"qrc:/ui/remove.svg"
}
}
} // Image
ColorOverlay {
anchors.fill: nextImage
source: nextImage
color: datovkaPalette.windowText
}
MouseArea {
// visible only if canDetailBoxes
visible: (!canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes)
anchors.fill: parent
onClicked: {
// we must allow remove exist recipients from model.
if (!canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes) {
root.boxRemove(rDbID)
}
}
} // MouseArea
} // Rectangle
MouseArea {
anchors.fill: parent
onClicked: {
root.dbClicked(rDbID, rDbType, rDbName, rDbAddress, rDbEffectiveOvm)
}
}
Rectangle {
anchors.top: parent.bottom
height: 1
......
......@@ -72,6 +72,7 @@ ApplicationWindow {
property Component pageMessageDetail: PageMessageDetail {}
property Component pageMessageList: PageMessageList {}
property Component pageMessageSearch: PageMessageSearch {}
property Component pageSendMessage: PageSendMessage {}
property Component pageSettingsAccount: PageSettingsAccount {}
property Component pageSettingsGeneral: PageSettingsGeneral {}
property Component pageSettingsPin: PageSettingsPin {}
......
......@@ -40,6 +40,8 @@ Item {
property var pageView
property var statusBar
property string userName
// recipBoxModel (if not null) holds recipient list of send message page
property var recipBoxModel: null
/* These properties remember choice of ComboBoxes */
property string searchType: "GENERAL"
......@@ -53,10 +55,10 @@ Item {
Component.onCompleted: {
searchPhraseText.forceActiveFocus()
proxyDataboxModel.setSourceModel(databoxModel)
proxyDataboxModel.setSourceModel(foundBoxModel)
}
DataboxListModel {
id: databoxModel
id: foundBoxModel
Component.onCompleted: {
}
}
......@@ -247,7 +249,10 @@ Item {
if (page > 0) {
page = page-1
}
isds.findDataboxFulltext(userName, databoxModel, searchTextTmp, searchTypeTmp, searchScopeTmp, page)
isds.findDataboxFulltext(userName, foundBoxModel, searchTextTmp, searchTypeTmp, searchScopeTmp, page)
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
}
}
}
}
......@@ -281,7 +286,10 @@ Item {
anchors.fill: parent
onClicked: {
page = page+1
isds.findDataboxFulltext(userName, databoxModel, searchTextTmp, searchTypeTmp, searchScopeTmp, page)
isds.findDataboxFulltext(userName, foundBoxModel, searchTextTmp, searchTypeTmp, searchScopeTmp, page)
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
}
}
}
} // Rectangle
......@@ -307,15 +315,38 @@ Item {
width: parent.width
interactive: true
model: proxyDataboxModel
onDbClicked: {
canDetailBoxes: recipBoxModel == null
canSelectBoxes: recipBoxModel != null
canDeselectBoxes: recipBoxModel != null
onBoxSelect: {
var boxEntry = foundBoxModel.entry(boxId)
statusBar.visible = false
if (recipBoxModel != null) {
foundBoxModel.selectEntry(boxEntry.dbID, true)
recipBoxModel.addEntry(boxEntry)
}
}
onBoxDeselect: {
statusBar.visible = false
pageView.push(pageDataboxDetail, {
"pageView": pageView,
"statusBar": statusBar,
"userName": userName,
"dbID": dbID,
"dbType": dbType
}, StackView.Immediate)
if (recipBoxModel != null) {
foundBoxModel.selectEntry(boxId, false)
recipBoxModel.removeEntry(boxId)
}
}
onBoxDetail: {
var boxEntry = foundBoxModel.entry(boxId)
statusBar.visible = false
if (recipBoxModel == null) {
pageView.push(pageDataboxDetail, {
"pageView": pageView,
"statusBar": statusBar,
"userName": userName,
"dbID": boxEntry.dbID,
"dbType": boxEntry.dbType
}, StackView.Immediate)
}
}
} // DataboxList
Connections {
......@@ -329,7 +360,10 @@ Item {
searchTextTmp = searchPhraseText.text
searchTypeTmp = searchType
searchScopeTmp = searchScope
emptyList.visible = (isds.findDataboxFulltext(userName, databoxModel, searchPhraseText.text, searchType, searchScope, page) <= 0)
emptyList.visible = (isds.findDataboxFulltext(userName, foundBoxModel, searchPhraseText.text, searchType, searchScope, page) <= 0)
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
}
}
}
Connections {
......
......@@ -75,6 +75,11 @@ Component {
image: "qrc:/ui/account-box.svg"
showNext: true
}
ListElement {
index: 6
name: qsTr("Create message")
image: "qrc:/ui/pencil-box-outline.svg"
}
ListElement {
index: 5
name: qsTr("Find databox")
......@@ -186,6 +191,13 @@ Component {
"statusBar": statusBar,
"userName": userName,
}, StackView.Immediate)
} else if (index == 6) {
pageView.replace(pageSendMessage, {
"pageView": pageView,
"statusBar": statusBar,
"userName": userName,
"action": "new"
}, StackView.Immediate)
} else {
pageView.pop(StackView.Immediate)
}
......
This diff is collapsed.
......@@ -35,6 +35,7 @@
<file>ui/account-plus.svg</file>
<file>ui/account-remove.svg</file>
<file>ui/account-search.svg</file>
<file>ui/add.svg</file>
<file>ui/alert.svg</file>
<file>ui/archive.svg</file>
<file>ui/arrow-down-bold-circle.svg</file>
......@@ -73,6 +74,7 @@
<file>ui/magnify.svg</file>
<file>ui/paperclip.svg</file>
<file>ui/pencil-box-outline.svg</file>
<file>ui/remove.svg</file>
<file>ui/reply.svg</file>
<file>ui/settings.svg</file>
<file>ui/tag-text-outline.svg</file>
......@@ -89,6 +91,7 @@
<file>ui/down.svg</file>
<file>ui/next.svg</file>
<file>ui/save-to-disk.svg</file>
<file>ui/subtract.svg</file>
<file>ui/sync.svg</file>
<file>ui/sync-all.svg</file>
<file>ui/up.svg</file>
......@@ -120,6 +123,7 @@
<file>../qml/pages/PageMessageDetail.qml</file>
<file>../qml/pages/PageMessageList.qml</file>
<file>../qml/pages/PageMessageSearch.qml</file>
<file>../qml/pages/PageSendMessage.qml</file>
<file>../qml/pages/PageSettingsAccount.qml</file>
<file>../qml/pages/PageSettingsGeneral.qml</file>
<file>../qml/pages/PageSettingsPin.qml</file>
......
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
\ No newline at end of file
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
<path d="M0 0h24v24H0z" fill="none"/>
</svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none"/><g class="currentLayer" style=""><title>Layer 1</title><path fill="" fill-opacity="1" stroke="#000000" stroke-opacity="1" stroke-width="2" stroke-dasharray="none" stroke-linejoin="miter" stroke-linecap="butt" stroke-dashoffset="" fill-rule="nonzero" opacity="1" marker-start="" marker-mid="" marker-end="" d="M4.926829327936616,11.863414764404297 L19.31707319137263,11.863414764404297 " id="svg_6" class=""/></g></svg>
\ No newline at end of file
......@@ -40,6 +40,11 @@ Accounts::Accounts(QObject *parent)
{
}
bool Accounts::boxEffectiveOVM(const QString &userName)
{
return globAccountDbPtr->boxEffectiveOVM(userName);
}
void Accounts::updateNewMessageCounter(const QVariant &acntModelVariant,
const QString &userName)
{
......
......@@ -52,6 +52,15 @@ class Accounts : public QObject {
public:
Accounts(QObject *parent = Q_NULLPTR);
/*!
* @brief Check whether data box has effective OVM.
*
* @param[in] userName User name identifying account.
* @return True if data box has effective OVM.
*/
Q_INVOKABLE static
bool boxEffectiveOVM(const QString &userName);
/*!
* @brief Update new message counter.
*
......
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <QFileInfo>
#include <QSet>
#include "src/auxiliaries/attachment_helper.h"
/*
* There is list of know file extension sufixes. For these we have png images.
*/
const QSet<QString> knowExp = QSet<QString> () <<
"avi" << "bmp" << "doc" << "docx" << "dwg" << "gif" << "html" <<
"htm" << "jpeg" << "jpg" << "mpeg" << "mpg" << "mp3" << "ods" <<
"odt" << "pdf" << "png" << "ppt" << "pptx" << "rtf" << "tiff" <<
"txt" << "wav" << "xls" << "xlsx" << "xml" << "zfo";
QString getApproximatelyAttachmentFileSizeFromBase64(int base64Length)
{
QString str = "";
base64Length = base64Length * 3 / 4;
if (base64Length >= 1000) {
str = "~" + QString::number(base64Length / 1000) + " KB" ;
} else {
str = "~" + QString::number(base64Length) + " B" ;
}
return str;
}
QString getAttachmentFileIconFromFileExtension(QString fileName)
{
QString img = "qrc:/fileicons/fileicon_blank.png";
QFileInfo fi(fileName);
const QString ext = fi.suffix();
ext.toLower();
if (!ext.isNull()) {
if (knowExp.contains(ext)) {
img = "qrc:/fileicons/fileicon_" + ext + ".png";
}
}
return img;
}
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _ATTACHMENT_HELPER_H_
#define _ATTACHMENT_HELPER_H_
#include <QString>
/*!
* @brief Get aproximatle attachment file size from base64 length.
*
* @param[in] base64Length Base64 content length.
* @return Aproximatle file size string.
*/
QString getApproximatelyAttachmentFileSizeFromBase64(int base64Length);
/*!
* @brief Get attachment icon from attachment file extension.
*
* @param[in] fileName Attachment filename with extension.
* @return Attachment icon filename string.
*/
QString getAttachmentFileIconFromFileExtension(QString fileName);
#endif /* _ATTACHMENT_HELPER_H_ */
......@@ -29,6 +29,7 @@
#include <QUrl>
#include <QQmlEngine> /* qmlRegisterType */
#include "src/auxiliaries/attachment_helper.h"
#include "src/common.h"
#include "src/dialogues/dialogues.h"
#include "src/files.h"
......@@ -214,6 +215,17 @@ void getAttchment(FileDb::FileData &file, const QString &userName,
file = fDb->getFileContentFromDb(fileId);
}
QString Files::getAttachmentFileIcon(const QString &fileName)
{
return getAttachmentFileIconFromFileExtension(fileName);
}
qint64 Files::getAttachmentSizeInBytes(const QString &filePath)
{
QFileInfo fileInfo(filePath);
return fileInfo.size();
}
QByteArray Files::getAttachmentDb(const QString &userName,
const QString &msgIdStr, int fileId)
{
......@@ -279,6 +291,30 @@ void Files::openAttachment(const QString &fileName, const QByteArray &base64Data
if (!filePath.isEmpty()) {
qInfo() << "Creating temporary file" << filePath;
openAttachmentFromPath(filePath);
} else {
qCritical() << "Cannot create temporary file for" << fileName;
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Open attachment error"),
tr("Cannot save selected file to disk for opening."),
QString());
}
}
void Files::openAttachmentFromPath(const QString &filePath)
{
Q_ASSERT(!filePath.isEmpty());
if (filePath.isEmpty()) {
qCritical() << "File path is empty!";
return;
}
if (isZfoFile(filePath)) {
/* Don't open zfo files from here. */
Q_ASSERT(0);
qCritical() << "This should open ZFO files by itself.";
return;
}
#if defined Q_OS_IOS
UrlOpener urlOpener;
......@@ -295,13 +331,6 @@ void Files::openAttachment(const QString &fileName, const QByteArray &base64Data
tr("File: '%1'").arg(filePath));
}
#endif /* defined Q_OS_IOS */
} else {
qCritical() << "Cannot create temporary file for" << fileName;
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Open attachment error"),
tr("Cannot save selected file to disk for opening."),
QString());
}
}
void Files::sendAttachmentsWithEmailFromDb(const QString &userName,
......
......@@ -44,6 +44,24 @@ public:
*/
explicit Files(QObject *parent = Q_NULLPTR);
/*!
* @brief Get attachment file icon from file name.
*
* @param[in] fileName File name.
* @return File icon resources string.
*/
Q_INVOKABLE
QString getAttachmentFileIcon(const QString &fileName);
/*!
* @brief Get attachment file size in bytes.
*
* @param[in] filePath Path to file.
* @return File size in bytes.
*/
Q_INVOKABLE
qint64 getAttachmentSizeInBytes(const QString &filePath);
/*!
* @brief Obtain attachment from database.
*
......@@ -74,6 +92,12 @@ public:
void openAttachment(const QString &fileName,
const QByteArray &base64Data);
/*!
* @brief Open attachment from path in default application.
*/
Q_INVOKABLE static
void openAttachmentFromPath(const QString &filePath);
/*!
* @brief Send attachments from database with email application.
*
......
......@@ -95,6 +95,7 @@ const struct QmlTypeEntry qmlPages[] = {
{ "PageMessageDetail", 1, 0 },
{ "PageMessageList", 1, 0 },
{ "PageMessageSearch", 1, 0 },
{ "PageSendMessage", 1, 0 },
{ "PageSettingsAccount", 1, 0 },
{ "PageSettingsGeneral", 1, 0 },
{ "PageSettingsPin", 1, 0 },
......@@ -293,6 +294,7 @@ int main(int argc, char *argv[])
/* Register types into QML. */
AccountListModel::declareQML();
DataboxListModel::declareQML();
DataboxModelEntry::declareQML();
Dialogues::declareQML();
FileListModel::declareQML();
InteractionFilesystem::declareQML();
......
......@@ -26,8 +26,27 @@
#include "src/models/databoxmodel.h"
void DataboxModelEntry::declareQML(void)
{
qmlRegisterType<DataboxModelEntry>("cz.nic.mobileDatovka.modelEntries", 1, 0, "DataboxModelEntry");
qRegisterMetaType<DataboxModelEntry>();
}
DataboxModelEntry::DataboxModelEntry(QObject *parent)
: QObject(parent),
m_dbID(),
m_dbType(),
m_dbName(),
m_dbAddress(),
m_dbIC(),
m_dbEffectiveOVM(),
m_dbSendOptions()
{
}
DataboxModelEntry::DataboxModelEntry(const DataboxModelEntry &dme)
: m_dbID(dme.m_dbID),
: QObject(Q_NULLPTR),
m_dbID(dme.m_dbID),
m_dbType(dme.m_dbType),
m_dbName(dme.m_dbName),
m_dbAddress(dme.m_dbAddress),
......@@ -40,7 +59,8 @@ DataboxModelEntry::DataboxModelEntry(const DataboxModelEntry &dme)
DataboxModelEntry::DataboxModelEntry(const QString &dbID, const QString &dbType,
const QString &dbName, const QString &dbAddress, const QString &dbIC,
const QString &dbEffectiveOVM, const QString &dbSendOptions)
: m_dbID(dbID),
: QObject(Q_NULLPTR),
m_dbID(dbID),
m_dbType(dbType),
m_dbName(dbName),
m_dbAddress(dbAddress),
......@@ -50,6 +70,19 @@ DataboxModelEntry::DataboxModelEntry(const QString &dbID, const QString &dbType,
{
}
DataboxModelEntry &DataboxModelEntry::operator=(const DataboxModelEntry &entry)
{
m_dbID = entry.m_dbID;
m_dbType = entry.m_dbType;
m_dbName = entry.m_dbName;
m_dbAddress = entry.m_dbAddress;
m_dbIC = entry.m_dbIC;
m_dbEffectiveOVM = entry.m_dbEffectiveOVM;
m_dbSendOptions = entry.m_dbSendOptions;
return *this;
}
QString DataboxModelEntry::dbID(void) const
{
return m_dbID;
......@@ -120,6 +153,15 @@ void DataboxModelEntry::setDbSendOptions(const QString &dbSendOptions)
m_dbSendOptions = dbSendOptions;
}
DataboxModelEntry *DataboxModelEntry::fromVariant(const QVariant &entryVariant)
{
if (!entryVariant.canConvert<QObject *>()) {
return Q_NULLPTR;
}
QObject *obj = qvariant_cast<QObject *>(entryVariant);
return qobject_cast<DataboxModelEntry *>(obj);
}
void DataboxListModel::declareQML(void)
{
qmlRegisterType<DataboxListModel>("cz.nic.mobileDatovka.models", 1, 0, "DataboxListModel");
......@@ -129,20 +171,22 @@ void DataboxListModel::declareQML(void)
DataboxListModel::DataboxListModel(QObject *parent)
: QAbstractListModel(parent),
m_databoxes()
m_boxIds(),
m_entries()
{
}
DataboxListModel::DataboxListModel(const DataboxListModel &model,
QObject *parent)
: QAbstractListModel(parent),
m_databoxes(model.m_databoxes)
m_boxIds(model.m_boxIds),
m_entries(model.m_entries)
{
}
int DataboxListModel::rowCount(const QModelIndex &parent) const
{
return !parent.isValid() ? m_databoxes.size() : 0;
return !parent.isValid() ? m_boxIds.size() : 0;
}
QHash<int, QByteArray> DataboxListModel::roleNames(void) const
......@@ -156,39 +200,44 @@ QHash<int, QByteArray> DataboxListModel::roleNames(void) const
roles[ROLE_DB_IC] = "rDbIc";
roles[ROLE_DB_EFFECTIVE_OVM] = "rDbEffectiveOvm";
roles[ROLE_DB_SEND_OPTION] = "rDbSendOption";
roles[ROLE_DB_SELECTED] = "rDbSelected";
}
return roles;
}
QVariant DataboxListModel::data(const QModelIndex &index, int role) const
{
if ((index.row() < 0) || (index.row() >= m_databoxes.size())) {
if ((index.row() < 0) || (index.row() >= m_boxIds.size())) {
return QVariant();
}
const DataboxModelEntry &databox(m_databoxes.at(index.row()));
const QString &boxId(m_boxIds.at(index.row()));
const DataboxModelEntry &entry(m_entries[boxId].entry);
switch (role) {
case ROLE_DB_ID:
return databox.dbID();
return entry.dbID();
break;
case ROLE_DB_TYPE:
return databox.dbType();
return entry.dbType();
break;
case ROLE_DB_NAME:
return databox.dbName();
return entry.dbName();
break;
case ROLE_DB_ADDRESS:
return databox.dbAddress();
return entry.dbAddress();
break;
case ROLE_DB_IC:
return databox.dbIC();