From 3d7e55f13a743534bf6c040d413ca7aa12c5307c Mon Sep 17 00:00:00 2001
From: Inso <insomniak.fr@gmail.com>
Date: Sun, 16 Feb 2014 23:15:30 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20fenetre=20pour=20cr=C3=A9er?=
 =?UTF-8?q?=20son=20dividend?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .directory                                  |  6 ++
 Makefile                                    |  2 +-
 README.md                                   | 29 ++++++-
 res/ui/communityTabWidget.ui                | 31 +++++++-
 res/ui/issuanceDialog.ui                    | 87 ++++++++++++++++++++
 src/cutecoin/core/config.py                 |  4 +
 src/cutecoin/gui/addAccountDialog.py        |  1 +
 src/cutecoin/gui/communityTabWidget.py      | 12 +++
 src/cutecoin/gui/issuanceDialog.py          | 88 +++++++++++++++++++++
 src/cutecoin/gui/mainWindow.py              |  1 +
 src/cutecoin/models/account/__init__.py     | 14 ++++
 src/cutecoin/models/account/factory.py      |  5 +-
 src/cutecoin/models/community/__init__.py   | 15 ++++
 src/cutecoin/models/transaction/__init__.py |  3 +
 14 files changed, 293 insertions(+), 5 deletions(-)
 create mode 100644 .directory
 create mode 100644 res/ui/issuanceDialog.ui
 create mode 100644 src/cutecoin/gui/issuanceDialog.py

diff --git a/.directory b/.directory
new file mode 100644
index 00000000..de51075e
--- /dev/null
+++ b/.directory
@@ -0,0 +1,6 @@
+[Dolphin]
+Timestamp=2014,2,16,12,25,25
+Version=3
+
+[Settings]
+HiddenFilesShown=true
diff --git a/Makefile b/Makefile
index 15d694eb..4afec396 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ RESOURCE_DIR = res/ui
 COMPILED_DIR = src/cutecoin/gen_resources
  
 #UI files to compile
-UI_FILES = mainwindow.ui addAccountDialog.ui addCommunityDialog.ui communityTabWidget.ui
+UI_FILES = mainwindow.ui addAccountDialog.ui addCommunityDialog.ui communityTabWidget.ui issuanceDialog.ui
 #Qt resource files to compile
 RESOURCES = 
  
diff --git a/README.md b/README.md
index 9f0c9a4c..7787c391 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,31 @@
 cutecoin
 ========
 
-Qt Client for Ucoin project
+Qt Client for [Ucoin](http://www.ucoin.io) project.
+
+
+## Goal features
+  * Ucoin account management via wallets and communities
+  * Multi-currency
+  * Multi-community
+  * Multi-wallets
+  * Contacts messaging
+  * User-friendly coins transfer
+  * On-the-fly and automatic coins fusion and divisions for transactions
+  * Coins issuance policies : minimal space, minimal changes
+  * Community membership management via a voting interface
+
+## Current state
+### Done (master branch)
+  * Accounts management
+  * Communities viewing
+
+### Work in progress (dev branch)
+  * Wallets viewing
+
+### Todo
+  * Transfer
+  * Coins issuance
+  * Coins issuance policies
+  * Contacts and messaging
+  * Voting 
\ No newline at end of file
diff --git a/res/ui/communityTabWidget.ui b/res/ui/communityTabWidget.ui
index 41c59598..2c499cdb 100644
--- a/res/ui/communityTabWidget.ui
+++ b/res/ui/communityTabWidget.ui
@@ -33,7 +33,14 @@
      <item>
       <widget class="QLabel" name="label_2">
        <property name="text">
-        <string>Last issuance</string>
+        <string>Last issuances</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="issuanceButton">
+       <property name="text">
+        <string>Issue money</string>
        </property>
       </widget>
      </item>
@@ -45,5 +52,25 @@
   </layout>
  </widget>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>issuanceButton</sender>
+   <signal>clicked()</signal>
+   <receiver>CommunityTabWidget</receiver>
+   <slot>openIssuanceDialog()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>296</x>
+     <y>42</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>199</x>
+     <y>149</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>openIssuanceDialog()</slot>
+ </slots>
 </ui>
diff --git a/res/ui/issuanceDialog.ui b/res/ui/issuanceDialog.ui
new file mode 100644
index 00000000..f139380c
--- /dev/null
+++ b/res/ui/issuanceDialog.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>IssuanceDialog</class>
+ <widget class="QDialog" name="IssuanceDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QLabel" name="totalLabel">
+     <property name="text">
+      <string>Total : </string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>IssuanceDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>IssuanceDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/cutecoin/core/config.py b/src/cutecoin/core/config.py
index 7efb38bd..177904f9 100644
--- a/src/cutecoin/core/config.py
+++ b/src/cutecoin/core/config.py
@@ -7,6 +7,7 @@ Created on 7 févr. 2014
 import logging
 from optparse import OptionParser
 import os.path
+import gnupg
 
 
 home = os.path.expanduser("~")
@@ -38,6 +39,9 @@ def parseArguments(argv):
     else:
         logging.getLogger().propagate = False
 
+    logger = logging.getLogger("gnupg")
+    logger.setLevel(logging.INFO)
+
     parameters['home'] = options.home
 
     pass
\ No newline at end of file
diff --git a/src/cutecoin/gui/addAccountDialog.py b/src/cutecoin/gui/addAccountDialog.py
index 9c5a6b7e..32e04eee 100644
--- a/src/cutecoin/gui/addAccountDialog.py
+++ b/src/cutecoin/gui/addAccountDialog.py
@@ -34,6 +34,7 @@ class AddAccountDialog(QDialog, Ui_AddAccountDialog):
 
     def setData(self):
         gpg = gnupg.GPG()
+        self.pgpKeysList.clear()
         availableKeys = gpg.list_keys(True)
         for key in availableKeys:
             self.pgpKeysList.addItem(key['uids'][0])
diff --git a/src/cutecoin/gui/communityTabWidget.py b/src/cutecoin/gui/communityTabWidget.py
index 2b178c8f..3925f9ea 100644
--- a/src/cutecoin/gui/communityTabWidget.py
+++ b/src/cutecoin/gui/communityTabWidget.py
@@ -3,9 +3,12 @@ Created on 2 févr. 2014
 
 @author: inso
 '''
+
+import logging
 from PyQt5.QtWidgets import QWidget
 from cutecoin.models.community.membersListModel import MembersListModel
 from cutecoin.models.transaction.issuancesListModel import IssuancesListModel
+from cutecoin.gui.issuanceDialog import IssuanceDialog
 from cutecoin.gen_resources.communityTabWidget_uic import Ui_CommunityTabWidget
 
 class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
@@ -19,8 +22,17 @@ class CommunityTabWidget(QWidget, Ui_CommunityTabWidget):
         super(CommunityTabWidget, self).__init__()
         self.setupUi(self)
         self.community = community
+        self.account = account
         self.communityMembersList.setModel(MembersListModel(community))
         self.issuancesList.setModel(IssuancesListModel(account, community))
+        if self.account.issuedLastDividend(community):
+            self.issuanceButton.setEnabled(False)
+        else:
+            self.issuanceButton.setEnabled(True)
 
+    def openIssuanceDialog(self):
+        logging.debug("Display dialog")
+        issuanceDialog = IssuanceDialog(self.account, self.community)
+        issuanceDialog.exec_()
 
 
diff --git a/src/cutecoin/gui/issuanceDialog.py b/src/cutecoin/gui/issuanceDialog.py
new file mode 100644
index 00000000..a786e9f0
--- /dev/null
+++ b/src/cutecoin/gui/issuanceDialog.py
@@ -0,0 +1,88 @@
+'''
+Created on 2 févr. 2014
+
+@author: inso
+'''
+import logging
+from math import pow
+
+from PyQt5.QtWidgets import QDialog, QVBoxLayout, QFrame, QSlider, QLabel, QDialogButtonBox
+from PyQt5.QtCore import Qt, QSignalMapper
+
+from cutecoin.gen_resources.issuanceDialog_uic import Ui_IssuanceDialog
+
+class IssuanceDialog(QDialog, Ui_IssuanceDialog):
+    '''
+    classdocs
+    '''
+
+
+    def __init__(self, issuer, community):
+        '''
+        Constructor
+        '''
+        super(IssuanceDialog, self).__init__()
+        self.setupUi(self)
+        self.issuer = issuer
+        self.community = community
+        self.dividend = self.community.dividend()
+        self.coinMinimalPower = self.community.coinMinimalPower()
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+
+        self.sliders = []
+        self.slidersLabels = []
+        maxCoinPower = 1
+        nMax = 0
+        # We look for the power of 10 which is directly higher than the dividend
+        while maxCoinPower < self.dividend:
+            maxCoinPower = pow(10, nMax)
+            nMax += 1
+
+        # N max is the power just before the one we found
+
+        logging.debug("Pow max : " + str(nMax))
+
+        for i in range(self.coinMinimalPower, nMax):
+            self.generateSliderFrame(i)
+
+    def generateSliderFrame(self, n):
+        frame = QFrame(self)
+        frame.setLayout(QVBoxLayout())
+
+        label = QLabel(frame)
+        frame.layout().addWidget(label)
+
+        slider = QSlider(Qt.Horizontal, frame)
+        slider.setMinimum(0)
+        slider.setMaximum(9)
+        slider.valueChanged.connect(self.refreshTotal)
+
+        frame.layout().addWidget(slider)
+
+        label.setText("0 coins of " + str(pow(10, n)))
+
+
+        self.slidersLabels.append(label)
+        self.sliders.append(slider)
+
+        self.layout().insertWidget(n, frame)
+
+    def refreshTotal(self):
+        n = 0
+        total = 0
+        for slider in self.sliders:
+            self.slidersLabels[n].setText(str(slider.value()) + " coins of " + str(pow(10, n)))
+            self.totalLabel.setText("Total : " + str(total))
+            total += slider.value()*pow(10, n)
+            n += 1
+        self.totalLabel.setText("Total : " + str(total))
+        if total != self.dividend:
+            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        else:
+            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
+
+
+
+
+
+
diff --git a/src/cutecoin/gui/mainWindow.py b/src/cutecoin/gui/mainWindow.py
index c11c4f09..c56edffb 100644
--- a/src/cutecoin/gui/mainWindow.py
+++ b/src/cutecoin/gui/mainWindow.py
@@ -78,6 +78,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             self.accountNameLabel.setText("Current account : " + self.core.currentAccount.name)
             self.walletsList.setModel(WalletsListModel(self.core.currentAccount))
             self.walletContent.setModel(WalletListModel(self.core.currentAccount.wallets.walletsList[0]))
+            self.communitiesTab.clear()
             for community in self.core.currentAccount.communities.communitiesList:
                 communityTab = CommunityTabWidget(self.core.currentAccount, community)
                 self.communitiesTab.addTab(communityTab, community.name())
diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py
index 22bf3c8c..9211f74e 100644
--- a/src/cutecoin/models/account/__init__.py
+++ b/src/cutecoin/models/account/__init__.py
@@ -66,6 +66,20 @@ class Account(object):
                 issuances.append(trxFactory.createTransaction(issuance['sender'], issuance['number']))
         return issuances
 
+    def issuedLastDividend(self, community):
+        currentAmendmentNumber = community.amendmentNumber()
+
+        if community in self.communities.communitiesList:
+            dividendsData = community.ucoinRequest(ucoin.hdc.transactions.sender.issuance.Dividend(self.keyFingerprint(), currentAmendmentNumber))
+            for dividend in dividendsData:
+                # Small bug in ucoinpy library
+                if not isinstance(dividend, str):
+                    return True
+
+        return False
+
+
+
     def jsonify(self):
         data = {'name' : self.name,
                 'pgpKeyId' : self.pgpKeyId,
diff --git a/src/cutecoin/models/account/factory.py b/src/cutecoin/models/account/factory.py
index ba2c91fd..85971dfc 100644
--- a/src/cutecoin/models/account/factory.py
+++ b/src/cutecoin/models/account/factory.py
@@ -3,12 +3,16 @@ Created on 11 févr. 2014
 
 @author: inso
 '''
+
+import logging
+
 from cutecoin.models.account import Account
 from cutecoin.models.account.wallets import Wallets
 from cutecoin.models.account.communities import Communities
 from cutecoin.models.wallet import factory as walletFactory
 from cutecoin.models.community import factory as communityFactory
 
+
 def createAccount(pgpKeyId, name, communities):
     '''
     Constructor
@@ -29,7 +33,6 @@ def loadAccount(jsonData):
     account.name = jsonData['name']
     account.communities = Communities()
     account.wallets = Wallets()
-
     for communityData in jsonData['communities']:
         account.communities.communitiesList.append(communityFactory.loadCommunity(communityData, account))
     return account
\ No newline at end of file
diff --git a/src/cutecoin/models/community/__init__.py b/src/cutecoin/models/community/__init__.py
index 2825d08f..98b37e21 100644
--- a/src/cutecoin/models/community/__init__.py
+++ b/src/cutecoin/models/community/__init__.py
@@ -61,6 +61,21 @@ class Community(object):
     def name(self):
         return self.currency
 
+    def dividend(self):
+        currentAmendment = self.ucoinRequest(ucoin.hdc.amendments.Current())
+        return currentAmendment['dividend']
+
+    def coinMinimalPower(self):
+        currentAmendment = self.ucoinRequest(ucoin.hdc.amendments.Current())
+        if 'coinMinimalPower' in currentAmendment.keys():
+            return currentAmendment['coinMinimalPower']
+        else:
+            return 0
+
+    def amendmentNumber(self):
+        currentAmendment = self.ucoinRequest(ucoin.hdc.amendments.Current())
+        return currentAmendment['number']
+
     def jsonifyNodesList(self):
         data = []
         for node in self.knownNodes:
diff --git a/src/cutecoin/models/transaction/__init__.py b/src/cutecoin/models/transaction/__init__.py
index 171cf526..cec0028b 100644
--- a/src/cutecoin/models/transaction/__init__.py
+++ b/src/cutecoin/models/transaction/__init__.py
@@ -56,6 +56,9 @@ class Issuance(Transaction):
     '''
     def __init__(self):
         super(Issuance).__init__()
+        
+    def amendmentNumber(self):
+        self.community.ucoinRequest(ucoin.hdc.transactions.View(self.sender.pgpFingerprint + "-" + self.increment))
 
     def getText(self):
         return str(self.value) + " " + self.currency
-- 
GitLab