From cbffaeee68d649069e0964b4930d04c441a7b63c Mon Sep 17 00:00:00 2001 From: Hayden <39291167+hdnsimpson@users.noreply.github.com> Date: Tue, 19 Mar 2019 00:05:56 +1300 Subject: [PATCH] Core Wallet Community Fund UI Improvement (#428) * basic implementation of topMenu * fixed hover icon, ready to add ui * Assets for community fund button * Implemented community fund tab assets * added community fund page, Q_OBJECT not yet supported * cfund tab image gradient correction * cfund tab image text now static on hovering * added page widgets, fetches cfund proposals and paymetn requests * Fixed filters location when resizing + create payment button readable * available, locked, spent labels static on resizing + todo slider format * changes * Proposals and Payment request buttons centered on resizing * Default selection of 'All' radioButton * Enabled vertical scroll bar for browsing cfund proposals * v1 implementation of proposals buttons toggle * Pull cfund available and locked funds on refresh * added communityfunddisplay widget files * cfund stats formatting fixes * changed display widgets to more accurately represent proposals * cfundstats to correct decimal places * added base proposal display widget * changed cfundstats to 8dp * fixed changes to communityfunddisplay constructor * partially implemented community fund widget, need to add requested and duration dialog with resize on page * added frame and changed size of communityfunddisplay * proposal widgets hidden on refresh * finalised labels in community fund display wideget * Filtering * Addition of expired radio button * Expired filter functionality * Pending filter fix * Filters (but my vote) give correct proposals * hide buttons on display if the proposal/payment request cannot be voted apon * spent cfundstat label implemented * Removed trailing 0's from cfundstats * Format proposals nav requested * cfundstats labels edge case formatting fix * changed display is expired date not voting window duration, currently broken but buildable * Further number formatting improvements * started implementing the yes no button box * removed std::cout * logging community fund proposals expiry and recalculating (still incorrect) proposal vote time remaining * initial addition of communityfunddisplaydetailed.ui and other class files, this will display extra information on the community fund proposal * added default values to communityfunddisplaydetailed.ui * connected view details button on communityfunddisplay.ui to create a communityfunddisplaydetailed.ui dialog, initial implementation with fixed ui object names * added functionality to close button on communityfunddisplaydetailed.ui, it now also inherits palette of parent (navcoin styled window) * (not working but buildable) started voting implementation via communityfunddisplay.ui * add base files for communityfundcreateproposal class * create base files for communityfundcreatepaymentrequestdialog class, no implementation yet * label ui variables correctly and add widgets for communityfundcreatepaymentrequestdialog.ui and communityfundcreateproposaldialog.ui * started proposal/payment request button hooks * Format long proposal titles, prevent text run off * adding functionality to communityfundcreateproposal.ui * addition to validation of communityfundcreateproposal.ui * proposal transaction start * Proposals and payment request formatting fix * Create proposal/payment request button static size * proposals now will not change style (yay) * Voting disabled in detailed view when appropriate * Format NAV amounts correctly in detailed proposal view * Align items in detailed proposal view better * First implementation of proposals/p requests toggle * Removal of 'expired waiting for...' proposals out of non expired filters * 'Expired waiting for...' proposals now appear in expired filter * Accepted proposals correct expiry time * added hash of proposal to communityfundviewdetailed.ui, also implemented more of the labels in this ui file * Removed ability to vote on expired proposals * Voting removed from detailed expired proposal view * write appropriate duration labels for proposals * hooked up createpaymentrequest fields to button * remove cout * split create proposal and create payment request buttons so that both are viewable at the same time * Correct expiry times in detailed proposal view * fixed pending proposals tx blockhash detailed view * refresh cfund tab content on tab switch * added hash to detailedproposal dialog, started validation function for communityfundcreatepaymentrequest.ui * radio buttons now take toggle into account * First step to displaying voted for proposals * added new ui for communityfundpaymentrequestdisplay * Filter user votes and format spent cfundstat * your vote filter full implementation * proposals display with buttons coloured if voted for * Vote colour showing in proposal display on click * Added colour voting indicators to detailed proposal view * Implementation of yes/no voting on proposals * added validation highlight, started craeteproposal * added cancel vote button to proposal display widget * added cancel vote button to proposal detailed display widget * UI changes to payment request display * Implemented most of the functionality of the prequest display widget * First implementation of prequest displays * radio buttons no longer reset on toggle * cfund view consistent when changine tabs but still refreshes * added base implementation of qvalidatedplaintextedit * Added new ui for prequest detailed view * Static implementation of payment request detailed view * added reject message to create proposal * Prequest details field population and url change * Changed window names to better describe form * Hide txblockhash is proposal is pending * Amount formatting on prequest detail * Prequest detail status field showing correct string * Hide txblockhash if prequest is pending * Hide payment hash on non-accepted prequests * Temporary html link implementation * Ready to implement time info into prequest detail view * added basic functionality of sendcommunityfund.ui, now times out buttons correctly. Must change visual * Show when prequest is accepted/rejected/expired on detailed view * Fixed error message when clicking hyperlink * hooked up labels and proposal obj, added implementation for prequest dialog * added dialog to exec on click create proposal * fixed stylesheeting of qvalidatedplaintextedit * added success dialog ui * added error/form not correctly filled to createpaymentrequest * Build fixed * Basic success dialog implementation + window title changes * ability to close success dialog * added scrollable spinboxes to ease increase duration * success dialog links to navexplorer but link will not work yet * Made success dialog a fixed size * Added dialog when user has insufficient nav to create a proposal * added saving of vote button state across restarts * create proposal validation complete * added defined color scheme * changed voting colors and added refresh function to communityfunddisplay * added refresh function to display of prequest * create proposal logic (not working yet) * rename Q_SLOTS naming, removed prepended on_ as clash with auto connect/expected naming convention from Qt (expected corresponding signals) * added spinboxtriplet class in attempt to setstyleinvalid apon invalid entry * Proposal creation working with rpc commands * Creating proposals works * deletes apon refresh instead of hiding * Proposal success dialog links to correct url now * added append function to communityfundpage * Create payment request validation until SendMoney function * Changed createproposal form field name to ID * Removed rpcwallet dependecy from createproposal * Replaced ensurewalletisunlocked() * implemented the row column stuff * rename function Refresh -> refresh * added buttons to adjust to vote in communityfunddisplaypaymentrequest * Creation of payment requests finished * removed cancel button that sometimes appeared when proposal had recieved no votes * Formatted payment request confirmation form * tidy up communityfundpage.* now refreshes apon createproposal exit * Fixed proposal filtering without enough funds/before end of voting cycle * fix to previous commit * fixed merge lol * Fixed prequest filtering without enough funds/before end of voting cycle * Fixed the build * trimming communityfunddisplay.* * trimmed communityfundcreateproposaldialog.* * moved communityfund ui files * finished tidy up * spinbox progress * Payment request voting double up fix * fixed double up display * spinbox fix * removed spinboxtriad and fix compile warnings * merge previous * Removal of cfund dropdown * cfund notification now directs to the new cfund ui * Removal of cfund_voting * bolded fields and added dlg close apon sucessful creation * changed return values of proposal creation and payment request from bool to void * cfund notification improvements * fixed bug where community fund icon would sometimes not appear in menu and added word wrap to sendconfurmationdialog * Proposal/payment request description wraps correctly * Payment request confirmation title change * Proposals pending voting of payment requests have changed expiry fields * added length clipping to title * Format long descriptions in detailed views * Replaced hyphens with new lines for URL readability * Replaced hard coded voting cycle numbers * Expiry time hidden for proposals waiting for enough coins in the fund * Potential macos fix * Potential macos fix part 2 * added NAV to amount titles for creating proposals and payment requests * Removed type warnings from detailed views * Cfund tab filters by pending by default * removed unnessesary qt/moc file generation (removes compiler warnings) * Changed deadline to proposal duration * revert * Pending proposals/prequests 'voting period finishes in' replacement * Removed incorrect comment * Removed unnecessary import * Removed duplicate lines * Removed all references of cfund_voting (old cfund ui) * Removed duplicate lines in navcoin4-qt.files * removed nonexistant files from Navcoin-Qt.files, added some translation support and removed more headers * Fixed successful creation hyperlink and text * Removed faulty detailed title formatting * Display title formatting fix when using new lines * Use of variable COIN instead of hard coding value * Created formatDisplayAmount() function and implemented * Removed hard coded fee values * Implementation of No Vote filter, default when directed to cfund tab --- .gitignore | 3 +- src/Makefile.qt.include | 776 +++++++++-------- src/NavCoin4-Qt.files | 58 ++ src/consensus/cfund.cpp | 12 + src/consensus/cfund.h | 3 +- src/qt/NavCoin4.files | 1 + ...ommunityfundcreatepaymentrequestdialog.cpp | 351 ++++++++ .../communityfundcreatepaymentrequestdialog.h | 29 + src/qt/communityfundcreateproposaldialog.cpp | 276 +++++++ src/qt/communityfundcreateproposaldialog.h | 29 + src/qt/communityfunddisplay.cpp | 219 +++++ src/qt/communityfunddisplay.h | 32 + src/qt/communityfunddisplaydetailed.cpp | 212 +++++ src/qt/communityfunddisplaydetailed.h | 31 + src/qt/communityfunddisplaypaymentrequest.cpp | 214 +++++ src/qt/communityfunddisplaypaymentrequest.h | 32 + ...unityfunddisplaypaymentrequestdetailed.cpp | 217 +++++ ...mmunityfunddisplaypaymentrequestdetailed.h | 32 + src/qt/communityfundpage.cpp | 399 +++++++++ src/qt/communityfundpage.h | 68 ++ src/qt/communityfundsuccessdialog.cpp | 41 + src/qt/communityfundsuccessdialog.h | 28 + src/qt/forms/cfund_voting.cpp | 206 ----- src/qt/forms/cfund_voting.h | 43 - src/qt/forms/cfund_voting.ui | 205 ----- ...communityfundcreatepaymentrequestdialog.ui | 158 ++++ .../communityfundcreateproposaldialog.ui | 246 ++++++ src/qt/forms/communityfunddisplay.ui | 274 ++++++ src/qt/forms/communityfunddisplaydetailed.ui | 777 ++++++++++++++++++ .../communityfunddisplaypaymentrequest.ui | 224 +++++ ...munityfunddisplaypaymentrequestdetailed.ui | 742 +++++++++++++++++ src/qt/forms/communityfundpage.ui | 646 +++++++++++++++ src/qt/forms/communityfundsuccessdialog.ui | 158 ++++ src/qt/forms/moc_cfund_voting.cpp | 149 ---- src/qt/forms/sendcommunityfunddialog.ui | 348 ++++++++ src/qt/locale/navcoin_en.ts | 93 +-- src/qt/navcoin.qrc | 3 + src/qt/navcoingui.cpp | 69 +- src/qt/navcoingui.h | 11 +- src/qt/qvalidatedplaintextedit.cpp | 56 ++ src/qt/qvalidatedplaintextedit.h | 35 + src/qt/qvalidatedspinbox.cpp | 50 ++ src/qt/qvalidatedspinbox.h | 31 + src/qt/res/icons/community_fund_hover.png | Bin 0 -> 7933 bytes src/qt/res/icons/community_fund_ns.png | Bin 0 -> 6921 bytes src/qt/res/icons/community_fund_s.png | Bin 0 -> 6135 bytes src/qt/sendcommunityfunddialog.cpp | 150 ++++ src/qt/sendcommunityfunddialog.h | 40 + src/qt/ui_getaddresstoreceive.h | 18 +- src/qt/ui_navtechsetup.h | 2 +- src/qt/walletframe.cpp | 7 + src/qt/walletframe.h | 3 +- src/qt/walletview.cpp | 12 + src/qt/walletview.h | 4 + src/txdb.cpp | 28 + src/txdb.h | 1 + src/wallet/wallet.cpp | 13 + src/wallet/wallet.h | 2 + 58 files changed, 6772 insertions(+), 1095 deletions(-) create mode 100644 src/qt/communityfundcreatepaymentrequestdialog.cpp create mode 100644 src/qt/communityfundcreatepaymentrequestdialog.h create mode 100644 src/qt/communityfundcreateproposaldialog.cpp create mode 100644 src/qt/communityfundcreateproposaldialog.h create mode 100644 src/qt/communityfunddisplay.cpp create mode 100644 src/qt/communityfunddisplay.h create mode 100644 src/qt/communityfunddisplaydetailed.cpp create mode 100644 src/qt/communityfunddisplaydetailed.h create mode 100644 src/qt/communityfunddisplaypaymentrequest.cpp create mode 100644 src/qt/communityfunddisplaypaymentrequest.h create mode 100644 src/qt/communityfunddisplaypaymentrequestdetailed.cpp create mode 100644 src/qt/communityfunddisplaypaymentrequestdetailed.h create mode 100644 src/qt/communityfundpage.cpp create mode 100644 src/qt/communityfundpage.h create mode 100644 src/qt/communityfundsuccessdialog.cpp create mode 100644 src/qt/communityfundsuccessdialog.h delete mode 100644 src/qt/forms/cfund_voting.cpp delete mode 100644 src/qt/forms/cfund_voting.h delete mode 100644 src/qt/forms/cfund_voting.ui create mode 100644 src/qt/forms/communityfundcreatepaymentrequestdialog.ui create mode 100644 src/qt/forms/communityfundcreateproposaldialog.ui create mode 100644 src/qt/forms/communityfunddisplay.ui create mode 100644 src/qt/forms/communityfunddisplaydetailed.ui create mode 100644 src/qt/forms/communityfunddisplaypaymentrequest.ui create mode 100644 src/qt/forms/communityfunddisplaypaymentrequestdetailed.ui create mode 100644 src/qt/forms/communityfundpage.ui create mode 100644 src/qt/forms/communityfundsuccessdialog.ui delete mode 100644 src/qt/forms/moc_cfund_voting.cpp create mode 100644 src/qt/forms/sendcommunityfunddialog.ui create mode 100644 src/qt/qvalidatedplaintextedit.cpp create mode 100644 src/qt/qvalidatedplaintextedit.h create mode 100644 src/qt/qvalidatedspinbox.cpp create mode 100644 src/qt/qvalidatedspinbox.h create mode 100644 src/qt/res/icons/community_fund_hover.png create mode 100644 src/qt/res/icons/community_fund_ns.png create mode 100644 src/qt/res/icons/community_fund_s.png create mode 100644 src/qt/sendcommunityfunddialog.cpp create mode 100644 src/qt/sendcommunityfunddialog.h diff --git a/.gitignore b/.gitignore index 203086cb0..fc07a8cef 100755 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,5 @@ src/NavCoin4-Qt.creator.user # IDE specific .idea/* -.vscode \ No newline at end of file +.vscode +*.creator.user diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index c9c688dcc..dff749848 100755 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -3,177 +3,202 @@ EXTRA_LIBRARIES += qt/libnavcoinqt.a # navcoin qt core # QT_TS = \ - qt/locale/navcoin_af.ts \ - qt/locale/navcoin_af_ZA.ts \ - qt/locale/navcoin_ar.ts \ - qt/locale/navcoin_be_BY.ts \ - qt/locale/navcoin_bg.ts \ - qt/locale/navcoin_bg_BG.ts \ - qt/locale/navcoin_ca_ES.ts \ - qt/locale/navcoin_ca.ts \ - qt/locale/navcoin_ca@valencia.ts \ - qt/locale/navcoin_cs_CZ.ts \ - qt/locale/navcoin_cs.ts \ - qt/locale/navcoin_cy.ts \ - qt/locale/navcoin_da.ts \ - qt/locale/navcoin_de.ts \ - qt/locale/navcoin_el_GR.ts \ - qt/locale/navcoin_el.ts \ - qt/locale/navcoin_en_GB.ts \ - qt/locale/navcoin_en.ts \ - qt/locale/navcoin_eo.ts \ - qt/locale/navcoin_es_AR.ts \ - qt/locale/navcoin_es_CL.ts \ - qt/locale/navcoin_es_CO.ts \ - qt/locale/navcoin_es_DO.ts \ - qt/locale/navcoin_es_ES.ts \ - qt/locale/navcoin_es_MX.ts \ - qt/locale/navcoin_es.ts \ - qt/locale/navcoin_es_UY.ts \ - qt/locale/navcoin_es_VE.ts \ - qt/locale/navcoin_et.ts \ - qt/locale/navcoin_eu_ES.ts \ - qt/locale/navcoin_fa_IR.ts \ - qt/locale/navcoin_fa.ts \ - qt/locale/navcoin_fi.ts \ - qt/locale/navcoin_fr_CA.ts \ - qt/locale/navcoin_fr_FR.ts \ - qt/locale/navcoin_fr.ts \ - qt/locale/navcoin_gl.ts \ - qt/locale/navcoin_he.ts \ - qt/locale/navcoin_hi_IN.ts \ - qt/locale/navcoin_hr.ts \ - qt/locale/navcoin_hu.ts \ - qt/locale/navcoin_id_ID.ts \ - qt/locale/navcoin_it_IT.ts \ - qt/locale/navcoin_it.ts \ - qt/locale/navcoin_ja.ts \ - qt/locale/navcoin_ka.ts \ - qt/locale/navcoin_kk_KZ.ts \ - qt/locale/navcoin_ko_KR.ts \ - qt/locale/navcoin_ku_IQ.ts \ - qt/locale/navcoin_ky.ts \ - qt/locale/navcoin_la.ts \ - qt/locale/navcoin_lt.ts \ - qt/locale/navcoin_lv_LV.ts \ - qt/locale/navcoin_mk_MK.ts \ - qt/locale/navcoin_mn.ts \ - qt/locale/navcoin_ms_MY.ts \ - qt/locale/navcoin_nb.ts \ - qt/locale/navcoin_nl.ts \ - qt/locale/navcoin_pam.ts \ - qt/locale/navcoin_pl.ts \ - qt/locale/navcoin_pt_BR.ts \ - qt/locale/navcoin_pt_PT.ts \ - qt/locale/navcoin_ro_RO.ts \ - qt/locale/navcoin_ro.ts \ - qt/locale/navcoin_ru_RU.ts \ - qt/locale/navcoin_ru.ts \ - qt/locale/navcoin_sk.ts \ - qt/locale/navcoin_sl_SI.ts \ - qt/locale/navcoin_sq.ts \ - qt/locale/navcoin_sr@latin.ts \ - qt/locale/navcoin_sr.ts \ - qt/locale/navcoin_sv.ts \ - qt/locale/navcoin_ta.ts \ - qt/locale/navcoin_th_TH.ts \ - qt/locale/navcoin_tr_TR.ts \ - qt/locale/navcoin_tr.ts \ - qt/locale/navcoin_uk.ts \ - qt/locale/navcoin_ur_PK.ts \ - qt/locale/navcoin_uz@Cyrl.ts \ - qt/locale/navcoin_vi.ts \ - qt/locale/navcoin_vi_VN.ts \ - qt/locale/navcoin_zh_CN.ts \ - qt/locale/navcoin_zh_HK.ts \ - qt/locale/navcoin_zh.ts \ - qt/locale/navcoin_zh_TW.ts + qt/locale/navcoin_af.ts \ + qt/locale/navcoin_af_ZA.ts \ + qt/locale/navcoin_ar.ts \ + qt/locale/navcoin_be_BY.ts \ + qt/locale/navcoin_bg.ts \ + qt/locale/navcoin_bg_BG.ts \ + qt/locale/navcoin_ca_ES.ts \ + qt/locale/navcoin_ca.ts \ + qt/locale/navcoin_ca@valencia.ts \ + qt/locale/navcoin_cs_CZ.ts \ + qt/locale/navcoin_cs.ts \ + qt/locale/navcoin_cy.ts \ + qt/locale/navcoin_da.ts \ + qt/locale/navcoin_de.ts \ + qt/locale/navcoin_el_GR.ts \ + qt/locale/navcoin_el.ts \ + qt/locale/navcoin_en_GB.ts \ + qt/locale/navcoin_en.ts \ + qt/locale/navcoin_eo.ts \ + qt/locale/navcoin_es_AR.ts \ + qt/locale/navcoin_es_CL.ts \ + qt/locale/navcoin_es_CO.ts \ + qt/locale/navcoin_es_DO.ts \ + qt/locale/navcoin_es_ES.ts \ + qt/locale/navcoin_es_MX.ts \ + qt/locale/navcoin_es.ts \ + qt/locale/navcoin_es_UY.ts \ + qt/locale/navcoin_es_VE.ts \ + qt/locale/navcoin_et.ts \ + qt/locale/navcoin_eu_ES.ts \ + qt/locale/navcoin_fa_IR.ts \ + qt/locale/navcoin_fa.ts \ + qt/locale/navcoin_fi.ts \ + qt/locale/navcoin_fr_CA.ts \ + qt/locale/navcoin_fr_FR.ts \ + qt/locale/navcoin_fr.ts \ + qt/locale/navcoin_gl.ts \ + qt/locale/navcoin_he.ts \ + qt/locale/navcoin_hi_IN.ts \ + qt/locale/navcoin_hr.ts \ + qt/locale/navcoin_hu.ts \ + qt/locale/navcoin_id_ID.ts \ + qt/locale/navcoin_it_IT.ts \ + qt/locale/navcoin_it.ts \ + qt/locale/navcoin_ja.ts \ + qt/locale/navcoin_ka.ts \ + qt/locale/navcoin_kk_KZ.ts \ + qt/locale/navcoin_ko_KR.ts \ + qt/locale/navcoin_ku_IQ.ts \ + qt/locale/navcoin_ky.ts \ + qt/locale/navcoin_la.ts \ + qt/locale/navcoin_lt.ts \ + qt/locale/navcoin_lv_LV.ts \ + qt/locale/navcoin_mk_MK.ts \ + qt/locale/navcoin_mn.ts \ + qt/locale/navcoin_ms_MY.ts \ + qt/locale/navcoin_nb.ts \ + qt/locale/navcoin_nl.ts \ + qt/locale/navcoin_pam.ts \ + qt/locale/navcoin_pl.ts \ + qt/locale/navcoin_pt_BR.ts \ + qt/locale/navcoin_pt_PT.ts \ + qt/locale/navcoin_ro_RO.ts \ + qt/locale/navcoin_ro.ts \ + qt/locale/navcoin_ru_RU.ts \ + qt/locale/navcoin_ru.ts \ + qt/locale/navcoin_sk.ts \ + qt/locale/navcoin_sl_SI.ts \ + qt/locale/navcoin_sq.ts \ + qt/locale/navcoin_sr@latin.ts \ + qt/locale/navcoin_sr.ts \ + qt/locale/navcoin_sv.ts \ + qt/locale/navcoin_ta.ts \ + qt/locale/navcoin_th_TH.ts \ + qt/locale/navcoin_tr_TR.ts \ + qt/locale/navcoin_tr.ts \ + qt/locale/navcoin_uk.ts \ + qt/locale/navcoin_ur_PK.ts \ + qt/locale/navcoin_uz@Cyrl.ts \ + qt/locale/navcoin_vi.ts \ + qt/locale/navcoin_vi_VN.ts \ + qt/locale/navcoin_zh_CN.ts \ + qt/locale/navcoin_zh_HK.ts \ + qt/locale/navcoin_zh.ts \ + qt/locale/navcoin_zh_TW.ts QT_FORMS_UI = \ - qt/forms/addressbookpage.ui \ - qt/forms/askpassphrasedialog.ui \ - qt/forms/coincontroldialog.ui \ - qt/forms/editaddressdialog.ui \ - qt/forms/helpmessagedialog.ui \ - qt/forms/intro.ui \ - qt/forms/openuridialog.ui \ - qt/forms/optionsdialog.ui \ - qt/forms/overviewpage.ui \ - qt/forms/receivecoinsdialog.ui \ - qt/forms/receiverequestdialog.ui \ - qt/forms/debugwindow.ui \ - qt/forms/sendcoinsdialog.ui \ - qt/forms/sendcoinsentry.ui \ - qt/forms/signverifymessagedialog.ui \ - qt/forms/transactiondescdialog.ui \ - qt/navtechinit.ui \ - qt/navtechitem.ui \ - qt/navtechsetup.ui \ - qt/forms/cfund_voting.ui \ - qt/getaddresstoreceive.ui + qt/forms/addressbookpage.ui \ + qt/forms/askpassphrasedialog.ui \ + qt/forms/coincontroldialog.ui \ + qt/forms/editaddressdialog.ui \ + qt/forms/helpmessagedialog.ui \ + qt/forms/intro.ui \ + qt/forms/openuridialog.ui \ + qt/forms/optionsdialog.ui \ + qt/forms/overviewpage.ui \ + qt/forms/communityfunddisplaydetailed.ui \ + qt/forms/communityfundcreateproposaldialog.ui \ + qt/forms/communityfundcreatepaymentrequestdialog.ui \ + qt/forms/receivecoinsdialog.ui \ + qt/forms/receiverequestdialog.ui \ + qt/forms/debugwindow.ui \ + qt/forms/sendcoinsdialog.ui \ + qt/forms/sendcoinsentry.ui \ + qt/forms/sendcommunityfunddialog.ui \ + qt/forms/communityfundsuccessdialog.ui \ + qt/forms/signverifymessagedialog.ui \ + qt/forms/transactiondescdialog.ui \ + qt/forms/communityfundpage.ui \ + qt/forms/communityfunddisplay.ui \ + qt/forms/communityfunddisplaypaymentrequest.ui \ + qt/forms/communityfunddisplaypaymentrequestdetailed.ui \ + qt/navtechinit.ui \ + qt/navtechitem.ui \ + qt/navtechsetup.ui \ + qt/getaddresstoreceive.ui QT_MOC_CPP = \ - qt/moc_addressbookpage.cpp \ - qt/moc_addresstablemodel.cpp \ - qt/moc_askpassphrasedialog.cpp \ - qt/moc_bantablemodel.cpp \ - qt/moc_navcoinaddressvalidator.cpp \ - qt/moc_navcoinamountfield.cpp \ - qt/moc_navcoingui.cpp \ - qt/moc_navcoinunits.cpp \ - qt/moc_clientmodel.cpp \ - qt/moc_coincontroldialog.cpp \ - qt/moc_coincontroltreewidget.cpp \ - qt/moc_coldstakingwizard.cpp \ - qt/moc_csvmodelwriter.cpp \ - qt/moc_editaddressdialog.cpp \ - qt/moc_guiutil.cpp \ - qt/moc_intro.cpp \ - qt/moc_macdockiconhandler.cpp \ - qt/moc_macnotificationhandler.cpp \ - qt/moc_navtechinit.cpp \ - qt/moc_navtechsetup.cpp \ - qt/forms/moc_cfund_voting.cpp \ - qt/moc_navtechitem.cpp \ - qt/moc_getaddresstoreceive.cpp \ - qt/moc_notificator.cpp \ - qt/moc_openuridialog.cpp \ - qt/moc_optionsdialog.cpp \ - qt/moc_optionsmodel.cpp \ - qt/moc_overviewpage.cpp \ - qt/moc_peertablemodel.cpp \ - qt/moc_paymentserver.cpp \ - qt/moc_qvalidatedlineedit.cpp \ - qt/moc_qvaluecombobox.cpp \ - qt/moc_receivecoinsdialog.cpp \ - qt/moc_receiverequestdialog.cpp \ - qt/moc_recentrequeststablemodel.cpp \ - qt/moc_rpcconsole.cpp \ - qt/moc_sendcoinsdialog.cpp \ - qt/moc_sendcoinsentry.cpp \ - qt/moc_signverifymessagedialog.cpp \ - qt/moc_splashscreen.cpp \ - qt/moc_trafficgraphwidget.cpp \ - qt/moc_transactiondesc.cpp \ - qt/moc_transactiondescdialog.cpp \ - qt/moc_transactionfilterproxy.cpp \ - qt/moc_transactiontablemodel.cpp \ - qt/moc_transactionview.cpp \ - qt/moc_utilitydialog.cpp \ - qt/moc_walletframe.cpp \ - qt/moc_walletmodel.cpp \ - qt/moc_walletview.cpp + qt/moc_addressbookpage.cpp \ + qt/moc_addresstablemodel.cpp \ + qt/moc_askpassphrasedialog.cpp \ + qt/moc_bantablemodel.cpp \ + qt/moc_navcoinaddressvalidator.cpp \ + qt/moc_navcoinamountfield.cpp \ + qt/moc_navcoingui.cpp \ + qt/moc_navcoinunits.cpp \ + qt/moc_clientmodel.cpp \ + qt/moc_coincontroldialog.cpp \ + qt/moc_coincontroltreewidget.cpp \ + qt/moc_coldstakingwizard.cpp \ + qt/moc_csvmodelwriter.cpp \ + qt/moc_editaddressdialog.cpp \ + qt/moc_guiutil.cpp \ + qt/moc_intro.cpp \ + qt/moc_macdockiconhandler.cpp \ + qt/moc_macnotificationhandler.cpp \ + qt/moc_navtechinit.cpp \ + qt/moc_navtechsetup.cpp \ + qt/moc_navtechitem.cpp \ + qt/moc_getaddresstoreceive.cpp \ + qt/moc_notificator.cpp \ + qt/moc_openuridialog.cpp \ + qt/moc_optionsdialog.cpp \ + qt/moc_optionsmodel.cpp \ + qt/moc_overviewpage.cpp \ + qt/moc_communityfundpage.cpp \ + qt/moc_communityfunddisplay.cpp \ + qt/moc_communityfunddisplaypaymentrequest.cpp \ + qt/moc_communityfunddisplaypaymentrequestdetailed.cpp \ + qt/moc_communityfundcreateproposaldialog.cpp \ + qt/moc_communityfundcreatepaymentrequestdialog.cpp \ + qt/moc_peertablemodel.cpp \ + qt/moc_paymentserver.cpp \ + qt/moc_qvalidatedlineedit.cpp \ + qt/moc_qvalidatedplaintextedit.cpp \ + qt/moc_qvalidatedspinbox.cpp \ + qt/moc_qvaluecombobox.cpp \ + qt/moc_receivecoinsdialog.cpp \ + qt/moc_receiverequestdialog.cpp \ + qt/moc_recentrequeststablemodel.cpp \ + qt/moc_rpcconsole.cpp \ + qt/moc_sendcoinsdialog.cpp \ + qt/moc_sendcoinsentry.cpp \ + qt/moc_sendcommunityfunddialog.cpp \ + qt/moc_communityfundsuccessdialog.cpp \ + qt/moc_signverifymessagedialog.cpp \ + qt/moc_splashscreen.cpp \ + qt/moc_trafficgraphwidget.cpp \ + qt/moc_transactiondesc.cpp \ + qt/moc_transactiondescdialog.cpp \ + qt/moc_transactionfilterproxy.cpp \ + qt/moc_transactiontablemodel.cpp \ + qt/moc_transactionview.cpp \ + qt/moc_utilitydialog.cpp \ + qt/moc_walletframe.cpp \ + qt/moc_walletmodel.cpp \ + qt/moc_walletview.cpp \ + qt/moc_communityfunddisplaydetailed.cpp NAVCOIN_MM = \ - qt/macdockiconhandler.mm \ - qt/macnotificationhandler.mm + qt/macdockiconhandler.mm \ + qt/macnotificationhandler.mm QT_MOC = \ - qt/navcoin.moc \ - qt/navcoinamountfield.moc \ - qt/intro.moc \ - qt/overviewpage.moc \ - qt/rpcconsole.moc + qt/navcoin.moc \ + qt/navcoinamountfield.moc \ + qt/intro.moc \ + qt/overviewpage.moc \ + qt/rpcconsole.moc \ + qt/communityfundpage.moc \ + qt/communityfunddisplay.moc \ + qt/communityfunddisplaypaymentrequest.moc \ + qt/communityfunddisplaypaymentrequestdetailed.moc \ + qt/communityfunddisplaydetailed.moc \ + qt/communityfundcreateproposaldialog.moc \ + qt/communityfundcreatepaymentrequestdialog.moc QT_QRC_CPP = qt/qrc_navcoin.cpp QT_QRC = qt/navcoin.qrc @@ -185,170 +210,184 @@ PROTOBUF_H = qt/paymentrequest.pb.h PROTOBUF_PROTO = qt/paymentrequest.proto NAVCOIN_QT_H = \ - qt/addressbookpage.h \ - qt/addresstablemodel.h \ - qt/askpassphrasedialog.h \ - qt/bantablemodel.h \ - qt/navcoinaddressvalidator.h \ - qt/navcoinamountfield.h \ - qt/navcoingui.h \ - qt/navcoinunits.h \ - qt/clientmodel.h \ - qt/coincontroldialog.h \ - qt/coincontroltreewidget.h \ - qt/coldstakingwizard.h \ - qt/csvmodelwriter.h \ - qt/editaddressdialog.h \ - qt/guiconstants.h \ - qt/guiutil.h \ - qt/intro.h \ - qt/listview.h \ - qt/macdockiconhandler.h \ - qt/macnotificationhandler.h \ - qt/navtechinit.h \ - qt/navtechitem.h \ - qt/navtechsetup.h \ - qt/forms/cfund_voting.h \ - qt/getaddresstoreceive.h \ - qt/networkstyle.h \ - qt/notificator.h \ - qt/openuridialog.h \ - qt/optionsdialog.h \ - qt/optionsmodel.h \ - qt/overviewpage.h \ - qt/paymentrequestplus.h \ - qt/paymentserver.h \ - qt/peertablemodel.h \ - qt/platformstyle.h \ - qt/qvalidatedlineedit.h \ - qt/qvaluecombobox.h \ - qt/receivecoinsdialog.h \ - qt/receiverequestdialog.h \ - qt/recentrequeststablemodel.h \ - qt/rpcconsole.h \ - qt/sendcoinsdialog.h \ - qt/sendcoinsentry.h \ - qt/signverifymessagedialog.h \ - qt/skinize.h \ - qt/splashscreen.h \ - qt/trafficgraphwidget.h \ - qt/transactiondesc.h \ - qt/transactiondescdialog.h \ - qt/transactionfilterproxy.h \ - qt/transactionrecord.h \ - qt/transactiontablemodel.h \ - qt/transactionview.h \ - qt/utilitydialog.h \ - qt/walletframe.h \ - qt/walletmodel.h \ - qt/walletmodeltransaction.h \ - qt/walletview.h \ - qt/winshutdownmonitor.h + qt/addressbookpage.h \ + qt/addresstablemodel.h \ + qt/askpassphrasedialog.h \ + qt/bantablemodel.h \ + qt/navcoinaddressvalidator.h \ + qt/navcoinamountfield.h \ + qt/navcoingui.h \ + qt/navcoinunits.h \ + qt/clientmodel.h \ + qt/coincontroldialog.h \ + qt/coincontroltreewidget.h \ + qt/coldstakingwizard.h \ + qt/csvmodelwriter.h \ + qt/editaddressdialog.h \ + qt/guiconstants.h \ + qt/guiutil.h \ + qt/intro.h \ + qt/listview.h \ + qt/macdockiconhandler.h \ + qt/macnotificationhandler.h \ + qt/navtechinit.h \ + qt/navtechitem.h \ + qt/navtechsetup.h \ + qt/getaddresstoreceive.h \ + qt/networkstyle.h \ + qt/notificator.h \ + qt/openuridialog.h \ + qt/optionsdialog.h \ + qt/optionsmodel.h \ + qt/overviewpage.h \ + qt/communityfundpage.h \ + qt/communityfunddisplay.h \ + qt/communityfunddisplaypaymentrequest.h \ + qt/communityfunddisplaypaymentrequestdetailed.h \ + qt/communityfunddisplaydetailed.h \ + qt/communityfundcreateproposaldialog.h \ + qt/communityfundcreatepaymentrequestdialog.h \ + qt/paymentrequestplus.h \ + qt/paymentserver.h \ + qt/peertablemodel.h \ + qt/platformstyle.h \ + qt/qvalidatedlineedit.h \ + qt/qvalidatedplaintextedit.h \ + qt/qvalidatedspinbox.h \ + qt/qvaluecombobox.h \ + qt/receivecoinsdialog.h \ + qt/receiverequestdialog.h \ + qt/recentrequeststablemodel.h \ + qt/rpcconsole.h \ + qt/sendcoinsdialog.h \ + qt/sendcoinsentry.h \ + qt/sendcommunityfunddialog.h \ + qt/communityfundsuccessdialog.h \ + qt/signverifymessagedialog.h \ + qt/skinize.h \ + qt/splashscreen.h \ + qt/trafficgraphwidget.h \ + qt/transactiondesc.h \ + qt/transactiondescdialog.h \ + qt/transactionfilterproxy.h \ + qt/transactionrecord.h \ + qt/transactiontablemodel.h \ + qt/transactionview.h \ + qt/utilitydialog.h \ + qt/walletframe.h \ + qt/walletmodel.h \ + qt/walletmodeltransaction.h \ + qt/walletview.h \ + qt/winshutdownmonitor.h RES_ICONS = \ - qt/res/icons/background_top.png \ - qt/res/icons/navcoin.png \ - qt/res/icons/navcoin.ico \ - qt/res/icons/navcoin_testnet.ico \ - qt/res/icons/ghost.png \ - qt/res/icons/address-book.png \ - qt/res/icons/quit.png \ - qt/res/icons/send.png \ - qt/res/icons/connect0.png \ - qt/res/icons/connect1.png \ - qt/res/icons/connect2.png \ - qt/res/icons/connect3.png \ - qt/res/icons/connect4.png \ - qt/res/icons/transaction0.png \ - qt/res/icons/transaction2.png \ - qt/res/icons/transaction_conflicted.png \ - qt/res/icons/clock1.png \ - qt/res/icons/clock2.png \ - qt/res/icons/clock3.png \ - qt/res/icons/clock4.png \ - qt/res/icons/clock5.png \ - qt/res/icons/eye.png \ - qt/res/icons/eye_minus.png \ - qt/res/icons/eye_plus.png \ - qt/res/icons/configure.png \ - qt/res/icons/receive.png \ - qt/res/icons/editpaste.png \ - qt/res/icons/editcopy.png \ - qt/res/icons/add.png \ - qt/res/icons/edit.png \ - qt/res/icons/history.png \ - qt/res/icons/overview.png \ - qt/res/icons/export.png \ - qt/res/icons/synced.png \ - qt/res/icons/remove.png \ - qt/res/icons/tx_mined.png \ - qt/res/icons/tx_input.png \ - qt/res/icons/tx_output.png \ - qt/res/icons/tx_inout.png \ - qt/res/icons/lock_closed.png \ - qt/res/icons/lock_open.png \ - qt/res/icons/key.png \ - qt/res/icons/filesave.png \ - qt/res/icons/splash.png \ - qt/res/icons/debugwindow.png \ - qt/res/icons/open.png \ - qt/res/icons/info.png \ - qt/res/icons/about.png \ - qt/res/icons/about_qt.png \ - qt/res/icons/verify.png \ - qt/res/icons/warning.png \ - qt/res/icons/fontbigger.png \ - qt/res/icons/fontsmaller.png \ - qt/res/icons/chevron.png \ - qt/res/icons/transaction_abandoned.png \ - qt/res/icons/logo_ns.png \ - qt/res/icons/home_ns.png \ - qt/res/icons/receive_ns.png \ - qt/res/icons/send_ns.png \ - qt/res/icons/home_hover.png \ - qt/res/icons/home_s.png \ - qt/res/icons/receive_hover.png \ - qt/res/icons/receive_s.png \ - qt/res/icons/send_hover.png \ - qt/res/icons/send_s.png \ - qt/res/icons/transaction_ns.png \ - qt/res/icons/transaction_s.png \ - qt/res/icons/transaction_hover.png \ - qt/res/fonts/roboto.ttf \ - qt/res/fonts/robotoregular.ttf \ - qt/res/fonts/source.ttf \ - qt/res/fonts/Roboto-Black.ttf \ - qt/res/fonts/Roboto-Bold.ttf \ - qt/res/fonts/Roboto-Medium.ttf + qt/res/icons/background_top.png \ + qt/res/icons/navcoin.png \ + qt/res/icons/navcoin.ico \ + qt/res/icons/navcoin_testnet.ico \ + qt/res/icons/ghost.png \ + qt/res/icons/address-book.png \ + qt/res/icons/quit.png \ + qt/res/icons/send.png \ + qt/res/icons/connect0.png \ + qt/res/icons/connect1.png \ + qt/res/icons/connect2.png \ + qt/res/icons/connect3.png \ + qt/res/icons/connect4.png \ + qt/res/icons/transaction0.png \ + qt/res/icons/transaction2.png \ + qt/res/icons/transaction_conflicted.png \ + qt/res/icons/clock1.png \ + qt/res/icons/clock2.png \ + qt/res/icons/clock3.png \ + qt/res/icons/clock4.png \ + qt/res/icons/clock5.png \ + qt/res/icons/eye.png \ + qt/res/icons/eye_minus.png \ + qt/res/icons/eye_plus.png \ + qt/res/icons/configure.png \ + qt/res/icons/receive.png \ + qt/res/icons/editpaste.png \ + qt/res/icons/editcopy.png \ + qt/res/icons/add.png \ + qt/res/icons/edit.png \ + qt/res/icons/history.png \ + qt/res/icons/overview.png \ + qt/res/icons/export.png \ + qt/res/icons/synced.png \ + qt/res/icons/remove.png \ + qt/res/icons/tx_mined.png \ + qt/res/icons/tx_input.png \ + qt/res/icons/tx_output.png \ + qt/res/icons/tx_inout.png \ + qt/res/icons/lock_closed.png \ + qt/res/icons/lock_open.png \ + qt/res/icons/key.png \ + qt/res/icons/filesave.png \ + qt/res/icons/splash.png \ + qt/res/icons/debugwindow.png \ + qt/res/icons/open.png \ + qt/res/icons/info.png \ + qt/res/icons/about.png \ + qt/res/icons/about_qt.png \ + qt/res/icons/verify.png \ + qt/res/icons/warning.png \ + qt/res/icons/fontbigger.png \ + qt/res/icons/fontsmaller.png \ + qt/res/icons/chevron.png \ + qt/res/icons/transaction_abandoned.png \ + qt/res/icons/logo_ns.png \ + qt/res/icons/home_ns.png \ + qt/res/icons/receive_ns.png \ + qt/res/icons/send_ns.png \ + qt/res/icons/home_hover.png \ + qt/res/icons/home_s.png \ + qt/res/icons/receive_hover.png \ + qt/res/icons/receive_s.png \ + qt/res/icons/send_hover.png \ + qt/res/icons/send_s.png \ + qt/res/icons/transaction_ns.png \ + qt/res/icons/transaction_s.png \ + qt/res/icons/transaction_hover.png \ + qt/res/icons/community_fund_ns.png \ + qt/res/icons/community_fund_s.png \ + qt/res/icons/community_fund_hover.png \ + qt/res/fonts/roboto.ttf \ + qt/res/fonts/robotoregular.ttf \ + qt/res/fonts/source.ttf \ + qt/res/fonts/Roboto-Black.ttf \ + qt/res/fonts/Roboto-Bold.ttf \ + qt/res/fonts/Roboto-Medium.ttf NAVCOIN_QT_CPP = \ - qt/bantablemodel.cpp \ - qt/navcoinaddressvalidator.cpp \ - qt/navcoinamountfield.cpp \ - qt/navcoingui.cpp \ - qt/navcoinunits.cpp \ - qt/navtechinit.cpp \ - qt/navtechitem.cpp \ - qt/navtechsetup.cpp \ - qt/forms/cfund_voting.cpp \ - qt/getaddresstoreceive.cpp \ - qt/clientmodel.cpp \ - qt/csvmodelwriter.cpp \ - qt/guiutil.cpp \ - qt/intro.cpp \ - qt/networkstyle.cpp \ - qt/notificator.cpp \ - qt/optionsdialog.cpp \ - qt/optionsmodel.cpp \ - qt/peertablemodel.cpp \ - qt/platformstyle.cpp \ - qt/qvalidatedlineedit.cpp \ - qt/qvaluecombobox.cpp \ - qt/rpcconsole.cpp \ - qt/skinize.cpp \ - qt/splashscreen.cpp \ - qt/trafficgraphwidget.cpp \ - qt/utilitydialog.cpp + qt/bantablemodel.cpp \ + qt/navcoinaddressvalidator.cpp \ + qt/navcoinamountfield.cpp \ + qt/navcoingui.cpp \ + qt/navcoinunits.cpp \ + qt/navtechinit.cpp \ + qt/navtechitem.cpp \ + qt/navtechsetup.cpp \ + qt/getaddresstoreceive.cpp \ + qt/clientmodel.cpp \ + qt/csvmodelwriter.cpp \ + qt/guiutil.cpp \ + qt/intro.cpp \ + qt/networkstyle.cpp \ + qt/notificator.cpp \ + qt/optionsdialog.cpp \ + qt/optionsmodel.cpp \ + qt/peertablemodel.cpp \ + qt/platformstyle.cpp \ + qt/qvalidatedlineedit.cpp \ + qt/qvalidatedplaintextedit.cpp \ + qt/qvalidatedspinbox.cpp \ + qt/qvaluecombobox.cpp \ + qt/rpcconsole.cpp \ + qt/skinize.cpp \ + qt/splashscreen.cpp \ + qt/trafficgraphwidget.cpp \ + qt/utilitydialog.cpp if TARGET_WINDOWS NAVCOIN_QT_CPP += qt/winshutdownmonitor.cpp @@ -356,33 +395,42 @@ endif if ENABLE_WALLET NAVCOIN_QT_CPP += \ - qt/addressbookpage.cpp \ - qt/addresstablemodel.cpp \ - qt/askpassphrasedialog.cpp \ - qt/coincontroldialog.cpp \ - qt/coincontroltreewidget.cpp \ - qt/coldstakingwizard.cpp \ - qt/editaddressdialog.cpp \ - qt/openuridialog.cpp \ - qt/overviewpage.cpp \ - qt/paymentrequestplus.cpp \ - qt/paymentserver.cpp \ - qt/receivecoinsdialog.cpp \ - qt/receiverequestdialog.cpp \ - qt/recentrequeststablemodel.cpp \ - qt/sendcoinsdialog.cpp \ - qt/sendcoinsentry.cpp \ - qt/signverifymessagedialog.cpp \ - qt/transactiondesc.cpp \ - qt/transactiondescdialog.cpp \ - qt/transactionfilterproxy.cpp \ - qt/transactionrecord.cpp \ - qt/transactiontablemodel.cpp \ - qt/transactionview.cpp \ - qt/walletframe.cpp \ - qt/walletmodel.cpp \ - qt/walletmodeltransaction.cpp \ - qt/walletview.cpp + qt/addressbookpage.cpp \ + qt/addresstablemodel.cpp \ + qt/askpassphrasedialog.cpp \ + qt/coincontroldialog.cpp \ + qt/coincontroltreewidget.cpp \ + qt/coldstakingwizard.cpp \ + qt/editaddressdialog.cpp \ + qt/openuridialog.cpp \ + qt/overviewpage.cpp \ + qt/communityfundpage.cpp \ + qt/communityfunddisplay.cpp \ + qt/communityfunddisplaypaymentrequest.cpp \ + qt/communityfunddisplaypaymentrequestdetailed.cpp \ + qt/communityfunddisplaydetailed.cpp \ + qt/communityfundcreateproposaldialog.cpp \ + qt/communityfundcreatepaymentrequestdialog.cpp \ + qt/paymentrequestplus.cpp \ + qt/paymentserver.cpp \ + qt/receivecoinsdialog.cpp \ + qt/receiverequestdialog.cpp \ + qt/recentrequeststablemodel.cpp \ + qt/sendcoinsdialog.cpp \ + qt/sendcoinsentry.cpp \ + qt/sendcommunityfunddialog.cpp \ + qt/communityfundsuccessdialog.cpp \ + qt/signverifymessagedialog.cpp \ + qt/transactiondesc.cpp \ + qt/transactiondescdialog.cpp \ + qt/transactionfilterproxy.cpp \ + qt/transactionrecord.cpp \ + qt/transactiontablemodel.cpp \ + qt/transactionview.cpp \ + qt/walletframe.cpp \ + qt/walletmodel.cpp \ + qt/walletmodeltransaction.cpp \ + qt/walletview.cpp endif RES_IMAGES = @@ -392,17 +440,17 @@ RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png) NAVCOIN_RC = qt/res/navcoin-qt-res.rc NAVCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \ - -I$(builddir)/qt/forms -DQT_NO_KEYWORDS + -I$(builddir)/qt/forms -DQT_NO_KEYWORDS qt_libnavcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(NAVCOIN_INCLUDES) $(NAVCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) + $(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) qt_libnavcoinqt_a_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_libnavcoinqt_a_SOURCES = $(NAVCOIN_QT_CPP) $(NAVCOIN_QT_H) $(QT_FORMS_UI) \ - $(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) + $(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) nodist_qt_libnavcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \ - $(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP) + $(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP) # forms/foo.h -> forms/ui_foo.h QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h)))) @@ -419,15 +467,15 @@ $(QT_MOC_CPP): $(PROTOBUF_H) # navcoin-qt binary # qt_navcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(NAVCOIN_INCLUDES) $(CURL_INCLUDES) $(NAVCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) + $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) qt_navcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) -qt_navcoin_qt_SOURCES = qt/navcoin.cpp +qt_navcoin_qt_SOURCES=qt/navcoin.cpp if TARGET_DARWIN - qt_navcoin_qt_SOURCES += $(NAVCOIN_MM) + qt_navcoin_qt_SOURCES+=$(NAVCOIN_MM) endif if TARGET_WINDOWS - qt_navcoin_qt_SOURCES += $(NAVCOIN_RC) + qt_navcoin_qt_SOURCES += $(NAVCOIN_RC) endif qt_navcoin_qt_LDADD = qt/libnavcoinqt.a $(LIBNAVCOIN_SERVER) if ENABLE_WALLET @@ -437,8 +485,8 @@ if ENABLE_ZMQ qt_navcoin_qt_LDADD += $(LIBNAVCOIN_ZMQ) $(ZMQ_LIBS) endif qt_navcoin_qt_LDADD += $(LIBNAVCOIN_CLI) $(LIBNAVCOIN_COMMON) $(LIBNAVCOIN_UTIL) $(LIBNAVCOIN_CONSENSUS) $(LIBNAVCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(UNBOUND_LIBS) $(SSL_LIBS) $(CURL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(UNBOUND_LIBS) $(SSL_LIBS) $(CURL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_navcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_navcoin_qt_LIBTOOLFLAGS = --tag CXX @@ -459,13 +507,13 @@ $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) @cp -f $< $(@D)/temp_$( $@ + $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ @rm $(@D)/temp_$( $@ + $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ CLEAN_QT = $(nodist_qt_libnavcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno @@ -483,11 +531,11 @@ ui_%.h: %.ui %.moc: %.cpp $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \ - $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ + $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ moc_%.cpp: %.h $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(DEFAULT_INCLUDES) $(QT_INCLUDES) $(MOC_DEFS) $< | \ - $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ + $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ %.qm: %.ts @test -f $(LRELEASE) diff --git a/src/NavCoin4-Qt.files b/src/NavCoin4-Qt.files index 43585b480..d80066556 100755 --- a/src/NavCoin4-Qt.files +++ b/src/NavCoin4-Qt.files @@ -1,5 +1,6 @@ Makefile.am Makefile.qt.include +NavCoin4-Qt.files addressindex.h addrman.cpp addrman.h @@ -283,6 +284,31 @@ qt/coincontroldialog.cpp qt/coincontroldialog.h qt/coincontroltreewidget.cpp qt/coincontroltreewidget.h +qt/communityfundcreatepaymentrequestdialog.cpp +qt/communityfundcreatepaymentrequestdialog.h +qt/communityfundcreatepaymentrequestdialog.moc +qt/communityfundcreateproposaldialog.cpp +qt/communityfundcreateproposaldialog.h +qt/communityfundcreateproposaldialog.moc +qt/communityfunddisplay.cpp +qt/communityfunddisplay.h +qt/communityfunddisplay.ui +qt/communityfunddisplaydetailed.cpp +qt/communityfunddisplaydetailed.h +qt/communityfunddisplaydetailed.moc +qt/communityfunddisplaypaymentrequest.cpp +qt/communityfunddisplaypaymentrequest.h +qt/communityfunddisplaypaymentrequest.ui +qt/communityfunddisplaypaymentrequestdetailed.cpp +qt/communityfunddisplaypaymentrequestdetailed.h +qt/communityfunddisplaypaymentrequestdetailed.ui +qt/communityfundpage.cpp +qt/communityfundpage.h +qt/communityfundpage.moc +qt/communityfundpage.ui +qt/communityfundsuccessdialog.cpp +qt/communityfundsuccessdialog.h +qt/communityfundsuccessdialog.ui qt/csvmodelwriter.cpp qt/csvmodelwriter.h qt/editaddressdialog.cpp @@ -292,6 +318,20 @@ qt/forms/TopmenuForm.ui.qml qt/forms/addressbookpage.ui qt/forms/askpassphrasedialog.ui qt/forms/coincontroldialog.ui +qt/forms/communityfundcreatepaymentrequestdialog.cpp +qt/forms/communityfundcreatepaymentrequestdialog.h +qt/forms/communityfundcreatepaymentrequestdialog.ui +qt/forms/communityfundcreateproposaldialog.cpp +qt/forms/communityfundcreateproposaldialog.h +qt/forms/communityfundcreateproposaldialog.ui +qt/forms/communityfunddisplay.ui +qt/forms/communityfunddisplaydetailed.cpp +qt/forms/communityfunddisplaydetailed.h +qt/forms/communityfunddisplaydetailed.ui +qt/forms/communityfunddisplaypaymentrequest.ui +qt/forms/communityfunddisplaypaymentrequestdetailed.ui +qt/forms/communityfundpage.ui +qt/forms/communityfundsuccessdialog.ui qt/forms/debugwindow.ui qt/forms/editaddressdialog.ui qt/forms/helpmessagedialog.ui @@ -303,11 +343,22 @@ qt/forms/receivecoinsdialog.ui qt/forms/receiverequestdialog.ui qt/forms/sendcoinsdialog.ui qt/forms/sendcoinsentry.ui +qt/forms/sendcommunityfunddialog.cpp +qt/forms/sendcommunityfunddialog.h +qt/forms/sendcommunityfunddialog.ui qt/forms/signverifymessagedialog.ui qt/forms/transactiondescdialog.ui qt/forms/ui_addressbookpage.h qt/forms/ui_askpassphrasedialog.h qt/forms/ui_coincontroldialog.h +qt/forms/ui_communityfundcreatepaymentrequestdialog.h +qt/forms/ui_communityfundcreateproposaldialog.h +qt/forms/ui_communityfunddisplay.h +qt/forms/ui_communityfunddisplaydetailed.h +qt/forms/ui_communityfunddisplaypaymentrequest.h +qt/forms/ui_communityfunddisplaypaymentrequestdetailed.h +qt/forms/ui_communityfundpage.h +qt/forms/ui_communityfundsuccessdialog.h qt/forms/ui_debugwindow.h qt/forms/ui_editaddressdialog.h qt/forms/ui_helpmessagedialog.h @@ -319,6 +370,7 @@ qt/forms/ui_receivecoinsdialog.h qt/forms/ui_receiverequestdialog.h qt/forms/ui_sendcoinsdialog.h qt/forms/ui_sendcoinsentry.h +qt/forms/ui_sendcommunityfunddialog.h qt/forms/ui_signverifymessagedialog.h qt/forms/ui_transactiondescdialog.h qt/getaddresstoreceive.cpp @@ -594,6 +646,10 @@ qt/qrc_navcoin.cpp qt/qrc_navcoin_locale.cpp qt/qvalidatedlineedit.cpp qt/qvalidatedlineedit.h +qt/qvalidatedplaintextedit.cpp +qt/qvalidatedplaintextedit.h +qt/qvalidatedspinbox.cpp +qt/qvalidatedspinbox.h qt/qvaluecombobox.cpp qt/qvaluecombobox.h qt/receivecoinsdialog.cpp @@ -608,6 +664,8 @@ qt/sendcoinsdialog.cpp qt/sendcoinsdialog.h qt/sendcoinsentry.cpp qt/sendcoinsentry.h +qt/sendcommunityfunddialog.cpp +qt/sendcommunityfunddialog.h qt/signverifymessagedialog.cpp qt/signverifymessagedialog.h qt/skinize.cpp diff --git a/src/consensus/cfund.cpp b/src/consensus/cfund.cpp index eecab4dd4..b75e441f1 100644 --- a/src/consensus/cfund.cpp +++ b/src/consensus/cfund.cpp @@ -391,6 +391,17 @@ bool CFund::CProposal::CanVote() const { return (fState == NIL) && (!ExceededMaxVotingCycles()); } +uint64_t CFund::CProposal::getTimeTillExpired(uint32_t currentTime) const +{ + if(nVersion >= 2) { + if (mapBlockIndex.count(blockhash) > 0) { + CBlockIndex* pblockindex = mapBlockIndex[blockhash]; + return currentTime - (pblockindex->GetBlockTime() + nDeadline); + } + } + return 0; +} + bool CFund::CProposal::IsExpired(uint32_t currentTime) const { if(nVersion >= 2) { if (fState == ACCEPTED && mapBlockIndex.count(blockhash) > 0) { @@ -490,3 +501,4 @@ void CFund::CPaymentRequest::ToJson(UniValue& ret) const { ret.push_back(Pair("paidOnBlock", paymenthash.ToString())); } } + diff --git a/src/consensus/cfund.h b/src/consensus/cfund.h index 97270e6fa..66d86ede4 100644 --- a/src/consensus/cfund.h +++ b/src/consensus/cfund.h @@ -238,6 +238,8 @@ class CProposal bool ExceededMaxVotingCycles() const; + uint64_t getTimeTillExpired(uint32_t currentTime) const; + bool CanVote() const; bool CanRequestPayments() const { @@ -317,7 +319,6 @@ class CProposal } } - }; } diff --git a/src/qt/NavCoin4.files b/src/qt/NavCoin4.files index 9e7568181..38aa2206b 100644 --- a/src/qt/NavCoin4.files +++ b/src/qt/NavCoin4.files @@ -12,6 +12,7 @@ coincontroldialog.cpp coincontroldialog.h coincontroltreewidget.cpp coincontroltreewidget.h +communityfundpage.ui csvmodelwriter.cpp csvmodelwriter.h editaddressdialog.cpp diff --git a/src/qt/communityfundcreatepaymentrequestdialog.cpp b/src/qt/communityfundcreatepaymentrequestdialog.cpp new file mode 100644 index 000000000..348b21ab7 --- /dev/null +++ b/src/qt/communityfundcreatepaymentrequestdialog.cpp @@ -0,0 +1,351 @@ +#include "communityfundcreatepaymentrequestdialog.h" +#include "ui_communityfundcreatepaymentrequestdialog.h" +#include "communityfundsuccessdialog.h" +#include "sendcommunityfunddialog.h" + +#include +#include "consensus/cfund.h" +#include "main.h" +#include "main.cpp" +#include "guiconstants.h" +#include "skinize.h" +#include "guiutil.h" +#include "sync.h" +#include "wallet/wallet.h" +#include "base58.h" +#include + +std::string random_str(size_t length) +{ + auto randchar = []() -> char + { + const char charset[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + const size_t max_index = (sizeof(charset) - 1); + return charset[ rand() % max_index ]; + }; + std::string str(length,0); + std::generate_n( str.begin(), length, randchar ); + return str; +} + +CommunityFundCreatePaymentRequestDialog::CommunityFundCreatePaymentRequestDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CommunityFundCreatePaymentRequestDialog) +{ + ui->setupUi(this); + + connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->pushButtonSubmitPaymentRequest, SIGNAL(clicked()), SLOT(click_pushButtonSubmitPaymentRequest())); +} + +bool CommunityFundCreatePaymentRequestDialog::validate() +{ + bool isValid = true; + + // Proposal hash; + if(!isActiveProposal(uint256S(ui->lineEditProposalHash->text().toStdString()))) + { + isValid = false; + ui->lineEditProposalHash->setValid(false); + } + + // Amount + if(!ui->lineEditRequestedAmount->validate()) + { + isValid = false; + ui->lineEditRequestedAmount->setValid(false); + } + + // Description + size_t desc_size = ui->plainTextEditDescription->toPlainText().toStdString().length(); + if(desc_size >= 1024 || desc_size == 0) + { + isValid = false; + ui->plainTextEditDescription->setValid(false); + } + else + { + ui->plainTextEditDescription->setValid(true); + } + + return isValid; +} + +void CommunityFundCreatePaymentRequestDialog::click_pushButtonSubmitPaymentRequest() +{ + + if(this->validate()) + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Get Proposal + CFund::CProposal proposal; + if(!CFund::FindProposal(ui->lineEditProposalHash->text().toStdString(), proposal)) { + QMessageBox msgBox(this); + std::string str = "Proposal could not be found with that hash\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Proposal not found"); + msgBox.exec(); + return; + } + if(proposal.fState != CFund::ACCEPTED) { + QMessageBox msgBox(this); + std::string str = "Proposals need to have been accepted to create a Payment Request for them\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Proposal not accepted"); + msgBox.exec(); + return; + } + + // Get Address + CNavCoinAddress address(proposal.Address); + if(!address.IsValid()) { + QMessageBox msgBox(this); + std::string str = "The address of the Proposal is not valid\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Address not valid"); + msgBox.exec(); + return; + } + + // Get KeyID + CKeyID keyID; + if (!address.GetKeyID(keyID)) { + QMessageBox msgBox(this); + std::string str = "The address does not refer to a key\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Address not valid"); + msgBox.exec(); + return; + } + + // Ensure wallet is unlocked + if (pwalletMain->IsLocked()) { + QMessageBox msgBox(this); + std::string str = "Please unlock the wallet\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + if (fWalletUnlockStakingOnly) { + QMessageBox msgBox(this); + std::string str = "Wallet is unlocked for staking only\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + + // Get Key + CKey key; + if (!pwalletMain->GetKey(keyID, key)) { + QMessageBox msgBox(this); + std::string str = "You are not the owner of the Proposal\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Not the owner"); + msgBox.exec(); + return; + } + + // Get fields from form + CAmount nReqAmount = ui->lineEditRequestedAmount->value(); + std::string id = ui->plainTextEditDescription->toPlainText().toStdString(); + std::string sRandom = random_str(16); + + // Construct Secret + std::string Secret = sRandom + "I kindly ask to withdraw " + + std::to_string(nReqAmount) + "NAV from the proposal " + + proposal.hash.ToString() + ". Payment request id: " + id; + + CHashWriter ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << Secret; + + // Attempt to sign + vector vchSig; + if (!key.SignCompact(ss.GetHash(), vchSig)) { + QMessageBox msgBox(this); + std::string str = "Failed to sign\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Sign Failed"); + msgBox.exec(); + return; + } + + // Create Signature + std::string Signature = EncodeBase64(&vchSig[0], vchSig.size()); + + // Validate requested amount + if (nReqAmount <= 0 || nReqAmount > proposal.GetAvailable(true)) { + QMessageBox msgBox(this); + std::string str = "Cannot create a Payment Request for the requested amount\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Invalid Amount"); + msgBox.exec(); + return; + } + + // Create wtx + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + UniValue strDZeel(UniValue::VOBJ); + + strDZeel.push_back(Pair("h",ui->lineEditProposalHash->text().toStdString())); + strDZeel.push_back(Pair("n",nReqAmount)); + strDZeel.push_back(Pair("s",Signature)); + strDZeel.push_back(Pair("r",sRandom)); + strDZeel.push_back(Pair("i",id)); + strDZeel.push_back(Pair("v",IsReducedCFundQuorumEnabled(pindexBestHeader, Params().GetConsensus()) ? CFund::CPaymentRequest::CURRENT_VERSION : 2)); + + wtx.strDZeel = strDZeel.write(); + wtx.nCustomVersion = CTransaction::PAYMENT_REQUEST_VERSION; + + // Validate wtx + if(wtx.strDZeel.length() > 1024) { + QMessageBox msgBox(this); + std::string str = "Description too long\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Invalid String"); + msgBox.exec(); + return; + } + + // Check balance + CAmount curBalance = pwalletMain->GetBalance(); + if (curBalance <= 10000) { + QMessageBox msgBox(this); + string fee = std::to_string(10000 / COIN); + std::string str = "You require at least " + fee + " NAV mature and available to create a payment request\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Insufficient NAV"); + msgBox.exec(); + return; + } + + // Create partial proposal object with all nessesary display fields from input and create confirmation dialog + { + // Create confirmation dialog + CFund::CPaymentRequest* preq = new CFund::CPaymentRequest(); + preq->nAmount = ui->lineEditRequestedAmount->value(); + preq->proposalhash = proposal.hash; + preq->strDZeel = ui->plainTextEditDescription->toPlainText().toStdString(); + + SendCommunityFundDialog dlg(this, preq, 10); + if(dlg.exec()== QDialog::Rejected) { + // User Declined to make the prequest + return; + } + else { + // User accepted making the prequest + // Parse NavCoin address + CScript CFContributionScript; + CScript scriptPubKey = GetScriptForDestination(address.Get()); + CFund::SetScriptForCommunityFundContribution(scriptPubKey); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CAmount nValue = 1000; + CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount, ""}; + vecSend.push_back(recipient); + + bool created_prequest = true; + + if (!pwalletMain->CreateTransaction(vecSend, wtx, reservekey, nFeeRequired, nChangePosRet, strError, NULL, true, "")) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance()) { + created_prequest = false; + } + } + if (!pwalletMain->CommitTransaction(wtx, reservekey)) { + created_prequest = false; + } + + // If the proposal was successfully made, confirm to the user it was made + if (created_prequest) { + // Display success UI + CommunityFundSuccessDialog dlg(wtx.GetHash(), this, preq); + dlg.exec(); + QDialog::accept(); + return; + } + else { + // Display something went wrong UI + QMessageBox msgBox(this); + std::string str = "Payment Request creation failed\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + } + } + } + else + { + QMessageBox msgBox(this); + QString str = tr("Please enter a valid:\n"); + if(!isActiveProposal(uint256S(ui->lineEditProposalHash->text().toStdString()))) + str += QString(tr("- Proposal Hash\n")); + if(!ui->lineEditRequestedAmount->validate()) + str += QString(tr("- Requested Amount\n")); + if(ui->plainTextEditDescription->toPlainText() == QString("") || ui->plainTextEditDescription->toPlainText().size() <= 0) + str += QString(tr("- Description\n")); + + msgBox.setText(str); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.exec(); + return; + } +} + +bool CommunityFundCreatePaymentRequestDialog::isActiveProposal(uint256 hash) +{ + std::vector vec; + if(pblocktree->GetProposalIndex(vec)) + { + if(std::find_if(vec.begin(), vec.end(), [&hash](CFund::CProposal& obj) {return obj.hash == hash;}) == vec.end()) + { + return false; + } + } + + return true; +} + +CommunityFundCreatePaymentRequestDialog::~CommunityFundCreatePaymentRequestDialog() +{ + delete ui; +} diff --git a/src/qt/communityfundcreatepaymentrequestdialog.h b/src/qt/communityfundcreatepaymentrequestdialog.h new file mode 100644 index 000000000..541f7b02a --- /dev/null +++ b/src/qt/communityfundcreatepaymentrequestdialog.h @@ -0,0 +1,29 @@ +#ifndef COMMUNITYFUNDCREATEPAYMENTREQUESTDIALOG_H +#define COMMUNITYFUNDCREATEPAYMENTREQUESTDIALOG_H + +#include +#include "../qvalidatedplaintextedit.h" +#include "uint256.h" + +namespace Ui { +class CommunityFundCreatePaymentRequestDialog; +} + +class CommunityFundCreatePaymentRequestDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CommunityFundCreatePaymentRequestDialog(QWidget *parent = 0); + ~CommunityFundCreatePaymentRequestDialog(); + +private: + Ui::CommunityFundCreatePaymentRequestDialog *ui; + bool validate(); + bool isActiveProposal(uint256 hash); + +public Q_SLOTS: + void click_pushButtonSubmitPaymentRequest(); +}; + +#endif // COMMUNITYFUNDCREATEPAYMENTREQUESTDIALOG_H diff --git a/src/qt/communityfundcreateproposaldialog.cpp b/src/qt/communityfundcreateproposaldialog.cpp new file mode 100644 index 000000000..36ca89dab --- /dev/null +++ b/src/qt/communityfundcreateproposaldialog.cpp @@ -0,0 +1,276 @@ +#include "communityfundcreateproposaldialog.h" +#include "ui_communityfundcreateproposaldialog.h" +#include "sendcommunityfunddialog.h" +#include "communityfundsuccessdialog.h" + +#include +#include +#include +#include + +#include "guiconstants.h" +#include "guiutil.h" +#include "sync.h" +#include "wallet/wallet.h" +#include "base58.h" +#include "main.h" +#include +#include "qvalidatedspinbox.h" + +CommunityFundCreateProposalDialog::CommunityFundCreateProposalDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CommunityFundCreateProposalDialog) +{ + ui->setupUi(this); + GUIUtil::setupAddressWidget(ui->lineEditNavcoinAddress, this); + + ui->spinBoxDays->setRange(0, 999999999); + ui->spinBoxHours->setRange(0, 24); + ui->spinBoxMinutes->setRange(0, 60); + + connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->pushButtonCreateProposal, SIGNAL(clicked()), this, SLOT(click_pushButtonCreateProposal())); + connect(ui->spinBoxDays, SIGNAL(clickedSpinBox()), this, SLOT(click_spinBox())); + connect(ui->spinBoxMinutes, SIGNAL(clickedSpinBox()), this, SLOT(click_spinBox())); + connect(ui->spinBoxHours, SIGNAL(clickedSpinBox()), this, SLOT(click_spinBox())); + + // Allow rollover of spinboxes + connect(ui->spinBoxMinutes, QOverload::of(&QSpinBox::valueChanged), + [=](int minutes){ + if(minutes == 60) + { + ui->spinBoxMinutes->setValue(0); + ui->spinBoxHours->setValue(ui->spinBoxHours->value()+1); + } + }); + connect(ui->spinBoxHours, QOverload::of(&QSpinBox::valueChanged), + [=](int hours){ + if(hours == 24) + { + ui->spinBoxHours->setValue(0); + ui->spinBoxDays->setValue(ui->spinBoxDays->value()+1); + } + }); + + string fee = std::to_string(Params().GetConsensus().nProposalMinimalFee / COIN); + string warning = "By submitting the proposal a " + fee + " NAV deduction will occur from your wallet "; + ui->labelWarning->setText(QString::fromStdString(warning)); +} + +// Validate input fields +bool CommunityFundCreateProposalDialog::validate() +{ + bool isValid = true; + if(!ui->lineEditNavcoinAddress->isValid() || (ui->lineEditNavcoinAddress->text() == QString(""))) + { + // Styling must be done manually as an empty field returns valid (true) + ui->lineEditNavcoinAddress->setStyleSheet(STYLE_INVALID); + ui->lineEditNavcoinAddress->setValid(false); + isValid = false; + } + if(!ui->lineEditRequestedAmount->validate()) + { + ui->lineEditRequestedAmount->setValid(false); + isValid = false; + } + size_t desc_length = ui->plainTextEditDescription->toPlainText().toStdString().length(); + if(desc_length >= 1024 || desc_length == 0) + { + isValid = false; + ui->plainTextEditDescription->setValid(false); + } + else + { + ui->plainTextEditDescription->setValid(true); + } + if(ui->spinBoxDays->value()*24*60*60 + ui->spinBoxHours->value()*60*60 + ui->spinBoxMinutes->value()*60 <= 0) + { + ui->spinBoxDays->setValid(false); + ui->spinBoxHours->setValid(false); + ui->spinBoxMinutes->setValid(false); + isValid = false; + } + + return isValid; +} + +// Q_SLOTS +void CommunityFundCreateProposalDialog::click_spinBox() { + ui->spinBoxDays->setValid(true); + ui->spinBoxHours->setValid(true); + ui->spinBoxMinutes->setValid(true); +} + +void CommunityFundCreateProposalDialog::click_pushButtonCreateProposal() +{ + if(this->validate()) + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + CNavCoinAddress address("NQFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ"); // Dummy address + + CWalletTx wtx; + bool fSubtractFeeFromAmount = false; + + // Address + string Address = ui->lineEditNavcoinAddress->text().toStdString().c_str(); + + // Requested Amount + CAmount nReqAmount = ui->lineEditRequestedAmount->value(); + + // Deadline + int64_t nDeadline = ui->spinBoxDays->value()*24*60*60 + ui->spinBoxHours->value()*60*60 + ui->spinBoxMinutes->value()*60; + + // Description + string sDesc = ui->plainTextEditDescription->toPlainText().toStdString(); + + UniValue strDZeel(UniValue::VOBJ); + + strDZeel.push_back(Pair("n",nReqAmount)); + strDZeel.push_back(Pair("a",Address)); + strDZeel.push_back(Pair("d",nDeadline)); + strDZeel.push_back(Pair("s",sDesc)); + strDZeel.push_back(Pair("v",IsReducedCFundQuorumEnabled(pindexBestHeader, Params().GetConsensus()) ? CFund::CProposal::CURRENT_VERSION : 2)); + + wtx.strDZeel = strDZeel.write(); + wtx.nCustomVersion = CTransaction::PROPOSAL_VERSION; + + if(wtx.strDZeel.length() > 1024) { + QMessageBox msgBox(this); + std::string str = "Please shorten your description\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Description too long"); + msgBox.exec(); + return; + } + + // Ensure wallet is unlocked + if (pwalletMain->IsLocked()) { + QMessageBox msgBox(this); + std::string str = "Please unlock the wallet\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + if (fWalletUnlockStakingOnly) { + QMessageBox msgBox(this); + std::string str = "Wallet is unlocked for staking only\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + + // Check balance + CAmount curBalance = pwalletMain->GetBalance(); + if (curBalance <= Params().GetConsensus().nProposalMinimalFee) { + QMessageBox msgBox(this); + string fee = std::to_string(Params().GetConsensus().nProposalMinimalFee / COIN); + std::string str = "You require at least " + fee + " NAV mature and available to create a proposal\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Insufficient NAV"); + msgBox.exec(); + return; + } + + // Create partial proposal object with all nessesary display fields from input and create confirmation dialog + { + CFund::CProposal *proposal = new CFund::CProposal(); + proposal->Address = Address; + proposal->nAmount = nReqAmount; + proposal->strDZeel = sDesc; + proposal->nDeadline = nDeadline; + + SendCommunityFundDialog dlg(this, proposal, 10); + if(dlg.exec() == QDialog::Rejected) + { + // User Declined to make the proposal + return; + } + else { + + // User accepted making the proposal + // Parse NavCoin address + CScript CFContributionScript; + CScript scriptPubKey = GetScriptForDestination(address.Get()); + CFund::SetScriptForCommunityFundContribution(scriptPubKey); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CAmount nFeeRequired; + std::string strError; + vector vecSend; + int nChangePosRet = -1; + CAmount nValue = Params().GetConsensus().nProposalMinimalFee; + CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount, ""}; + vecSend.push_back(recipient); + + bool created_proposal = true; + + if (!pwalletMain->CreateTransaction(vecSend, wtx, reservekey, nFeeRequired, nChangePosRet, strError, NULL, true, "")) { + if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance()) { + created_proposal = false; + } + } + if (!pwalletMain->CommitTransaction(wtx, reservekey)) { + created_proposal = false; + } + + // If the proposal was successfully made, confirm to the user it was made + if (created_proposal) { + // Display success UI and close current dialog + CommunityFundSuccessDialog dlg(wtx.GetHash(), this, proposal); + dlg.exec(); + QDialog::accept(); + return; + } + else { + // Display something went wrong UI + QMessageBox msgBox(this); + std::string str = "Proposal creation failed\n"; + msgBox.setText(tr(str.c_str())); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Error"); + msgBox.exec(); + return; + } + } + } + } + else + { + QMessageBox msgBox(this); + QString str = QString(tr("Please enter a valid:\n")); + if(!ui->lineEditNavcoinAddress->isValid() || (ui->lineEditNavcoinAddress->text() == QString(""))) + str += QString(tr("- Address\n")); + if(!ui->lineEditRequestedAmount->validate()) + str += QString(tr("- Requested Amount\n")); + if(ui->plainTextEditDescription->toPlainText() == QString("") || ui->plainTextEditDescription->toPlainText().size() <= 0) + str += QString(tr("- Description\n")); + if((ui->spinBoxDays->value()*24*60*60 + ui->spinBoxHours->value()*60*60 + ui->spinBoxMinutes->value()*60) <= 0) + str += QString(tr("- Duration\n")); + + msgBox.setText(str); + msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle("Please enter valid fields"); + msgBox.exec(); + return; + } + return; +} + +CommunityFundCreateProposalDialog::~CommunityFundCreateProposalDialog() +{ + delete ui; +} diff --git a/src/qt/communityfundcreateproposaldialog.h b/src/qt/communityfundcreateproposaldialog.h new file mode 100644 index 000000000..874687e52 --- /dev/null +++ b/src/qt/communityfundcreateproposaldialog.h @@ -0,0 +1,29 @@ +#ifndef COMMUNITYFUNDCREATEPROPOSALDIALOG_H +#define COMMUNITYFUNDCREATEPROPOSALDIALOG_H + +#include +#include "qvalidatedspinbox.h" + +namespace Ui { +class CommunityFundCreateProposalDialog; +} + +class CommunityFundCreateProposalDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CommunityFundCreateProposalDialog(QWidget *parent = 0); + ~CommunityFundCreateProposalDialog(); + +private: + Ui::CommunityFundCreateProposalDialog *ui; + bool validate(); + +private Q_SLOTS: + void click_pushButtonCreateProposal(); + void click_spinBox(); + +}; + +#endif // COMMUNITYFUNDCREATEPROPOSALDIALOG_H diff --git a/src/qt/communityfunddisplay.cpp b/src/qt/communityfunddisplay.cpp new file mode 100644 index 000000000..167b23562 --- /dev/null +++ b/src/qt/communityfunddisplay.cpp @@ -0,0 +1,219 @@ +#include "communityfunddisplay.h" +#include "ui_communityfunddisplay.h" + +#include +#include "main.h" +#include "../txdb.h" +#include +#include +#include +#include "wallet/wallet.h" +#include "base58.h" +#include "consensus/cfund.h" +#include "chain.h" +#include "guiutil.h" + +#include "communityfunddisplaydetailed.h" +#include "communityfundpage.h" + +CommunityFundDisplay::CommunityFundDisplay(QWidget *parent, CFund::CProposal proposal) : + QWidget(parent), + ui(new Ui::CommunityFundDisplay), + proposal(proposal) +{ + ui->setupUi(this); + + QFont f_title("Sans Serif", 10.5, QFont::Bold); + QFont f_label_title("Sans Serif", 10, QFont::Bold); + QFont f_label("Sans Serif", 10, QFont::Normal); + + ui->title->setFont(f_title); + ui->labelTitleDuration->setFont(f_label_title); + ui->labelDuration->setFont(f_label); + ui->labelTitleRequested->setFont(f_label_title); + ui->labelRequested->setFont(f_label); + ui->labelTitleStatus->setFont(f_label_title); + ui->labelStatus->setFont(f_label); + ui->pushButtonDetails->setFont(f_label); + ui->buttonBoxVote->setFont(f_label); + + connect(ui->buttonBoxVote, SIGNAL(clicked( QAbstractButton*)), this, SLOT(click_buttonBoxVote(QAbstractButton*))); + connect(ui->pushButtonDetails, SIGNAL(clicked()), this, SLOT(click_pushButtonDetails())); + + refresh(); +} + +void CommunityFundDisplay::refresh() +{ + // Set labels from community fund + ui->title->setText(QString::fromStdString(proposal.strDZeel)); + ui->labelStatus->setText(QString::fromStdString(proposal.GetState(pindexBestHeader->GetBlockTime()))); + + string nav_amount; + nav_amount = wallet->formatDisplayAmount(proposal.nAmount); + ui->labelRequested->setText(QString::fromStdString(nav_amount)); + + uint64_t proptime = 0; + if (mapBlockIndex.count(proposal.blockhash) > 0) { + proptime = mapBlockIndex[proposal.blockhash]->GetBlockTime(); + } + + uint64_t deadline = proptime + proposal.nDeadline - pindexBestHeader->GetBlockTime(); + uint64_t deadline_d = std::floor(deadline/86400); + uint64_t deadline_h = std::floor((deadline-deadline_d*86400)/3600); + uint64_t deadline_m = std::floor((deadline-(deadline_d*86400 + deadline_h*3600))/60); + + // Show appropriate amount of figures + std::string s_deadline = ""; + if(deadline_d >= 14) + s_deadline = std::to_string(deadline_d) + std::string(" Days"); + else + s_deadline = std::to_string(deadline_d) + std::string(" Days ") + std::to_string(deadline_h) + std::string(" Hours ") + std::to_string(deadline_m) + std::string(" Minutes"); + + ui->labelDuration->setText(QString::fromStdString(s_deadline)); + + // Hide ability to vote is the status is expired + std::string status = ui->labelStatus->text().toStdString(); + if (status.find("expired") != string::npos) { + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::NoButton); + } + + // If proposal is pending show voting cycles left + if (proposal.fState == CFund::NIL) + { + std::string duration_title = "Voting Cycle: "; + std::string duration = std::to_string(proposal.nVotingCycle) + " of " + std::to_string(Params().GetConsensus().nCyclesProposalVoting); + ui->labelTitleDuration->setText(QString::fromStdString(duration_title)); + ui->labelDuration->setText(QString::fromStdString(duration)); + } + + // If proposal is rejected, show when it was rejected + if (proposal.fState == CFund::REJECTED) + { + std::string expiry_title = "Rejected on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + + // If expired show when it expired + if (proposal.fState == CFund::EXPIRED || status.find("expired") != string::npos) + { + if (proposal.fState == CFund::EXPIRED) + { + std::string expiry_title = "Expired on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + else + { + std::string expiry_title = "Expires: "; + std::string expiry = "At end of voting period"; + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(expiry)); + } + } + + // Shade in yes/no buttons is user has voted + // If the proposal is pending and not prematurely expired (ie can be voted on): + if (proposal.fState == CFund::NIL && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") == string::npos) + { + // Get proposal votes list + CFund::CProposal prop = this->proposal; + auto it = std::find_if( vAddedProposalVotes.begin(), vAddedProposalVotes.end(), + [&prop](const std::pair& element){ return element.first == prop.hash.ToString();} ); + if (it != vAddedProposalVotes.end()) + { + if (it->second) + { + // Proposal was voted yes, shade in yes button and unshade no button + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + else + { + // Proposal was noted no, shade in no button and unshade yes button + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + } + } + else + { + // Proposal was not voted on, reset shades of both buttons + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + } + + // If a proposal is expired pending voting of payment requests, change the expiry label text + if(status.find("expired pending voting of payment requests") != string::npos) { + ui->labelDuration->setText(QString::fromStdString("After payment request voting")); + } + + //hide ui voting elements on proposals which are not allowed vote states + if(!proposal.CanVote()) + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::NoButton); + + // Prevent overflow of title + std::string title_string = proposal.strDZeel; + std::replace( title_string.begin(), title_string.end(), '\n', ' '); + if (title_string.length() > 140) + { + title_string = title_string.substr(0, 140); + title_string.append("..."); + } + ui->title->setText(QString::fromStdString(title_string)); + + // Hide expiry label is proposal is accepted and waiting for coins + if(status.find("accepted waiting for enough coins in fund") != string::npos) { + ui->labelDuration->setVisible(false); + ui->labelTitleDuration->setVisible(false); + } +} + +void CommunityFundDisplay::click_buttonBoxVote(QAbstractButton *button) +{ + // Cast the vote + bool duplicate = false; + + if (ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::YesRole) + { + CFund::VoteProposal(proposal.hash.ToString(), true, duplicate); + refresh(); + } + else if(ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::NoRole) + { + CFund::VoteProposal(proposal.hash.ToString(), false, duplicate); + refresh(); + } + else if(ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::RejectRole) + { + CFund::RemoveVoteProposal(proposal.hash.ToString()); + refresh(); + } + else + { + refresh(); + return; + } +} + +void CommunityFundDisplay::click_pushButtonDetails() +{ + CommunityFundDisplayDetailed dlg(this, proposal); + dlg.exec(); + refresh(); +} + +CommunityFundDisplay::~CommunityFundDisplay() +{ + delete ui; +} diff --git a/src/qt/communityfunddisplay.h b/src/qt/communityfunddisplay.h new file mode 100644 index 000000000..5ae8e762d --- /dev/null +++ b/src/qt/communityfunddisplay.h @@ -0,0 +1,32 @@ +#ifndef COMMUNITYFUNDDISPLAY_H +#define COMMUNITYFUNDDISPLAY_H + +#include "consensus/cfund.h" +#include "wallet/wallet.h" +#include +#include + +namespace Ui { +class CommunityFundDisplay; +} + +class CommunityFundDisplay : public QWidget +{ + Q_OBJECT + +public: + CommunityFundDisplay(QWidget *parent = 0, CFund::CProposal proposal = CFund::CProposal()); + ~CommunityFundDisplay(); + +private: + Ui::CommunityFundDisplay *ui; + CFund::CProposal proposal; + CWallet *wallet; + void refresh(); + +public Q_SLOTS: + void click_buttonBoxVote(QAbstractButton *button); + void click_pushButtonDetails(); +}; + +#endif // COMMUNITYFUNDDISPLAY_H diff --git a/src/qt/communityfunddisplaydetailed.cpp b/src/qt/communityfunddisplaydetailed.cpp new file mode 100644 index 000000000..eba15a0e9 --- /dev/null +++ b/src/qt/communityfunddisplaydetailed.cpp @@ -0,0 +1,212 @@ +#include "communityfunddisplaydetailed.h" +#include "ui_communityfunddisplaydetailed.h" +#include "communityfundpage.h" + +#include "main.h" +#include +#include +#include "wallet/wallet.h" +#include "base58.h" + +CommunityFundDisplayDetailed::CommunityFundDisplayDetailed(QWidget *parent, CFund::CProposal proposal) : + QDialog(parent), + ui(new Ui::CommunityFundDisplayDetailed), + proposal(proposal) +{ + ui->setupUi(this); + + //connect ui elements to functions + connect(ui->buttonBoxYesNoVote, SIGNAL(clicked( QAbstractButton*)), this, SLOT(click_buttonBoxYesNoVote(QAbstractButton*))); + connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->labelLinkToProposal, SIGNAL(linkActivated()), this, SLOT(go_to_explorer())); + + //update labels + setProposalLabels(); + + // Shade in yes/no buttons is user has voted + // If the proposal is pending and not prematurely expired (ie can be voted on): + if (proposal.fState == CFund::NIL && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") == string::npos) { + // Get proposal votes list + auto it = std::find_if( vAddedProposalVotes.begin(), vAddedProposalVotes.end(), + [&proposal](const std::pair& element){ return element.first == proposal.hash.ToString();} ); + if (it != vAddedProposalVotes.end()) { + if (it->second) { + // Proposal was voted yes, shade in yes button and unshade no button + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + else { + // Proposal was noted no, shade in no button and unshade yes button + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + } + } + else { + // Proposal was not voted on, reset shades of both buttons + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + } + + + //hide ui voting elements on proposals which are not allowed vote states + if(!proposal.CanVote()) + { + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::NoButton); + } + + // Hide ability to vote is the status is expired + std::string status = ui->labelStatus->text().toStdString(); + if (status.find("expired") != string::npos) { + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::NoButton); + } +} + +void CommunityFundDisplayDetailed::setProposalLabels() const +{ + ui->labelProposalTitle->setText(QString::fromStdString(proposal.strDZeel)); + ui->labelAddress->setText(QString::fromStdString(proposal.Address)); + + uint64_t deadline_d = std::floor(proposal.nDeadline/86400); + uint64_t deadline_h = std::floor((proposal.nDeadline-deadline_d*86400)/3600); + uint64_t deadline_m = std::floor((proposal.nDeadline-(deadline_d*86400 + deadline_h*3600))/60); + std::string s_deadline = std::to_string(deadline_d) + std::string(" Days ") + std::to_string(deadline_h) + std::string(" Hours ") + std::to_string(deadline_m) + std::string(" Minutes"); + + uint64_t proptime = 0; + if (mapBlockIndex.count(proposal.blockhash) > 0) { + proptime = mapBlockIndex[proposal.blockhash]->GetBlockTime(); + } + + ui->labelDeadline->setText(QString::fromStdString(s_deadline)); + if (proposal.fState == CFund::NIL) { + std::string expiry_title = "Voting period finishes in: "; + ui->labelExpiresInTitle->setText(QString::fromStdString(expiry_title)); + std::string expiry = std::to_string(Params().GetConsensus().nCyclesProposalVoting - proposal.nVotingCycle) + " voting cycles"; + ui->labelExpiresIn->setText(QString::fromStdString(expiry)); + } + if (proposal.fState == CFund::ACCEPTED) { + uint64_t deadline = proptime + proposal.nDeadline - pindexBestHeader->GetBlockTime(); + + uint64_t deadline_d = std::floor(deadline/86400); + uint64_t deadline_h = std::floor((deadline-deadline_d*86400)/3600); + uint64_t deadline_m = std::floor((deadline-(deadline_d*86400 + deadline_h*3600))/60); + + std::string s_deadline = ""; + if(deadline_d >= 14) + { + s_deadline = std::to_string(deadline_d) + std::string(" Days"); + } + else + { + s_deadline = std::to_string(deadline_d) + std::string(" Days ") + std::to_string(deadline_h) + std::string(" Hours ") + std::to_string(deadline_m) + std::string(" Minutes"); + } + ui->labelExpiresIn->setText(QString::fromStdString(s_deadline)); + } + if (proposal.fState == CFund::REJECTED) { + std::string expiry_title = "Rejected on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelExpiresInTitle->setText(QString::fromStdString(expiry_title)); + ui->labelExpiresIn->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + if (proposal.fState == CFund::EXPIRED || proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") != string::npos) { + if (proposal.fState == CFund::EXPIRED) { + std::string expiry_title = "Expired on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelExpiresInTitle->setText(QString::fromStdString(expiry_title)); + ui->labelExpiresIn->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + else { + std::string expiry_title = "Expires: "; + std::string expiry = "At end of voting period"; + ui->labelExpiresInTitle->setText(QString::fromStdString(expiry_title)); + ui->labelExpiresIn->setText(QString::fromStdString(expiry)); + } + } + ui->labelStatus->setText(QString::fromStdString(proposal.GetState(pindexBestHeader->GetBlockTime()))); + ui->labelNumberOfYesVotes->setText(QString::fromStdString(std::to_string(proposal.nVotesYes))); + ui->labelNumberOfNoVotes->setText(QString::fromStdString(std::to_string(proposal.nVotesNo))); + + ui->labelTransactionBlockHash->setText(QString::fromStdString(proposal.blockhash.ToString())); + ui->labelTransactionHash->setText(QString::fromStdString(proposal.txblockhash.ToString())); + ui->labelVersionNumber->setText(QString::fromStdString(std::to_string(proposal.nVersion))); + ui->labelVotingCycleNumber->setText(QString::fromStdString(std::to_string(proposal.nVotingCycle))); + ui->labelLinkToProposal->setText(QString::fromStdString("https://www.navexplorer.com/community-fund/proposal/" + proposal.hash.ToString())); + ui->labelProposalHash->setText(QString::fromStdString(proposal.hash.ToString())); + + + //set hyperlink for navcommunity proposal view + ui->labelLinkToProposal->setText("labelLinkToProposal->text() + "\">" + ui->labelLinkToProposal->text() + ""); + ui->labelLinkToProposal->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->labelLinkToProposal->setOpenExternalLinks(true); + + string amount; + amount = wallet->formatDisplayAmount(proposal.nAmount); + ui->labelAmount->setText(QString::fromStdString(amount)); + + string fee; + fee = wallet->formatDisplayAmount(proposal.nFee); + ui->labelFee->setText(QString::fromStdString(fee)); + + // If a proposal is expired pending voting of payment requests, change the expiry label text + std::string status = ui->labelStatus->text().toStdString(); + if(status.find("expired pending voting of payment requests") != string::npos) { + ui->labelExpiresIn->setText(QString::fromStdString("After payment request voting")); + } + + // If proposal is pending, hide the transaction hash + if (proposal.fState == CFund::NIL) { + ui->labelTransactionBlockHashTitle->setVisible(false); + ui->labelTransactionBlockHash->setVisible(false); + } + + ui->labelProposalTitle->setText(QString::fromStdString(proposal.strDZeel.c_str())); + + // Hide expiry label is proposal is accepted and waiting for coins + if(status.find("accepted waiting for enough coins in fund") != string::npos) { + ui->labelExpiresIn->setVisible(false); + ui->labelExpiresInTitle->setVisible(false); + } +} + +void CommunityFundDisplayDetailed::click_buttonBoxYesNoVote(QAbstractButton *button) +{ + //cast the vote + bool duplicate = false; + + if (ui->buttonBoxYesNoVote->buttonRole(button) == QDialogButtonBox::YesRole) + { + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + CFund::VoteProposal(proposal.hash.ToString(), true, duplicate); + } + else if(ui->buttonBoxYesNoVote->buttonRole(button) == QDialogButtonBox::NoRole) + { + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + CFund::VoteProposal(proposal.hash.ToString(), false, duplicate); + } + else if(ui->buttonBoxYesNoVote->buttonRole(button) == QDialogButtonBox::RejectRole) + { + ui->buttonBoxYesNoVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + CFund::RemoveVoteProposal(proposal.hash.ToString()); + } + else { + return; + } +} + +CommunityFundDisplayDetailed::~CommunityFundDisplayDetailed() +{ + delete ui; +} diff --git a/src/qt/communityfunddisplaydetailed.h b/src/qt/communityfunddisplaydetailed.h new file mode 100644 index 000000000..744da7308 --- /dev/null +++ b/src/qt/communityfunddisplaydetailed.h @@ -0,0 +1,31 @@ +#ifndef COMMUNITYFUNDDISPLAYDETAILED_H +#define COMMUNITYFUNDDISPLAYDETAILED_H + +#include "consensus/cfund.h" +#include "wallet/wallet.h" +#include +#include + +namespace Ui { +class CommunityFundDisplayDetailed; +} + +class CommunityFundDisplayDetailed : public QDialog +{ + Q_OBJECT + +public: + explicit CommunityFundDisplayDetailed(QWidget *parent = 0, CFund::CProposal proposal = CFund::CProposal()); + ~CommunityFundDisplayDetailed(); + +private: + Ui::CommunityFundDisplayDetailed *ui; + CFund::CProposal proposal; + CWallet *wallet; + void setProposalLabels() const; + +public Q_SLOTS: + void click_buttonBoxYesNoVote(QAbstractButton *button); +}; + +#endif // COMMUNITYFUNDDISPLAYDETAILED_H diff --git a/src/qt/communityfunddisplaypaymentrequest.cpp b/src/qt/communityfunddisplaypaymentrequest.cpp new file mode 100644 index 000000000..708ab33f5 --- /dev/null +++ b/src/qt/communityfunddisplaypaymentrequest.cpp @@ -0,0 +1,214 @@ +#include "communityfunddisplaypaymentrequest.h" +#include "ui_communityfunddisplaypaymentrequest.h" +#include "communityfundpage.h" +#include "communityfunddisplaypaymentrequestdetailed.h" + +#include +#include "main.h" +#include "../txdb.h" +#include +#include +#include +#include "consensus/cfund.h" +#include "wallet/wallet.h" +#include "base58.h" +#include "chain.h" + +CommunityFundDisplayPaymentRequest::CommunityFundDisplayPaymentRequest(QWidget *parent, CFund::CPaymentRequest prequest) : + QWidget(parent), + ui(new Ui::CommunityFundDisplayPaymentRequest), + prequest(prequest) +{ + ui->setupUi(this); + + QFont f_title("Sans Serif", 10.5, QFont::Bold); + QFont f_label_title("Sans Serif", 10, QFont::Bold); + QFont f_label("Sans Serif", 10, QFont::Normal); + + ui->title->setFont(f_title); + ui->labelTitleDuration->setFont(f_label_title); + ui->labelDuration->setFont(f_label); + ui->labelTitleRequested->setFont(f_label_title); + ui->labelRequested->setFont(f_label); + ui->labelTitleStatus->setFont(f_label_title); + ui->labelStatus->setFont(f_label); + ui->pushButtonDetails->setFont(f_label); + ui->buttonBoxVote->setFont(f_label); + + connect(ui->buttonBoxVote, SIGNAL(clicked( QAbstractButton*)), this, SLOT(click_buttonBoxVote(QAbstractButton*))); + connect(ui->pushButtonDetails, SIGNAL(clicked()), this, SLOT(click_pushButtonDetails())); + + refresh(); +} + +void CommunityFundDisplayPaymentRequest::refresh() +{ + // Set labels from community fund + ui->title->setText(QString::fromStdString(prequest.strDZeel)); + ui->labelStatus->setText(QString::fromStdString(prequest.GetState())); + + string nav_amount; + nav_amount = wallet->formatDisplayAmount(prequest.nAmount); + ui->labelRequested->setText(QString::fromStdString(nav_amount)); + + uint64_t proptime = 0; + if (mapBlockIndex.count(prequest.blockhash) > 0) { + proptime = mapBlockIndex[prequest.blockhash]->GetBlockTime(); + } + + uint64_t deadline = proptime - pindexBestHeader->GetBlockTime(); + uint64_t deadline_d = std::floor(deadline/86400); + uint64_t deadline_h = std::floor((deadline-deadline_d*86400)/3600); + uint64_t deadline_m = std::floor((deadline-(deadline_d*86400 + deadline_h*3600))/60); + + std::string s_deadline = ""; + if(deadline_d >= 14) + s_deadline = std::to_string(deadline_d) + std::string(" Days"); + else + s_deadline = std::to_string(deadline_d) + std::string(" Days ") + std::to_string(deadline_h) + std::string(" Hours ") + std::to_string(deadline_m) + std::string(" Minutes"); + + ui->labelDuration->setText(QString::fromStdString(s_deadline)); + + // Hide ability to vote is the status is expired + std::string status = ui->labelStatus->text().toStdString(); + if (status.find("expired") != string::npos) { + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::NoButton); + } + + // If prequest is accepted, show when it was accepted + if (prequest.fState == CFund::ACCEPTED) + { + std::string duration_title = "Accepted on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelTitleDuration->setText(QString::fromStdString(duration_title)); + ui->labelDuration->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + + // If prequest is pending show voting cycles left + if (prequest.fState == CFund::NIL) + { + std::string duration_title = "Voting Cycle: "; + std::string duration = std::to_string(prequest.nVotingCycle) + " of " + std::to_string(Params().GetConsensus().nCyclesPaymentRequestVoting); + ui->labelTitleDuration->setText(QString::fromStdString(duration_title)); + ui->labelDuration->setText(QString::fromStdString(duration)); + } + + // If prequest is rejected, show when it was rejected + if (prequest.fState == CFund::REJECTED) + { + std::string expiry_title = "Rejected on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + + // If expired show when it expired + if (prequest.fState == CFund::EXPIRED || status.find("expired") != string::npos) + { + if (prequest.fState == CFund::EXPIRED) + { + std::string expiry_title = "Expired on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + else + { + std::string expiry_title = "Expires: "; + std::string expiry = "At end of voting period"; + ui->labelTitleDuration->setText(QString::fromStdString(expiry_title)); + ui->labelDuration->setText(QString::fromStdString(expiry)); + } + } + + // Shade in yes/no buttons is user has voted + // If the prequest is pending and not prematurely expired (ie can be voted on): + if (prequest.fState == CFund::NIL && prequest.GetState().find("expired") == string::npos) + { + // Get prequest votes list + CFund::CPaymentRequest preq = prequest; + auto it = std::find_if( vAddedPaymentRequestVotes.begin(), vAddedPaymentRequestVotes.end(), + [&preq](const std::pair& element){ return element.first == preq.hash.ToString();} ); + if (it != vAddedPaymentRequestVotes.end()) + { + if (it->second) + { + // Prequest was voted yes, shade in yes button and unshade no button + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + else + { + // Prequest was noted no, shade in no button and unshade yes button + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + } + } + else + { + // Prequest was not voted on, reset shades of both buttons + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxVote->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxVote->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + + } + } + + //hide ui voting elements on proposals which are not allowed vote states + if(!prequest.CanVote()) + ui->buttonBoxVote->setStandardButtons(QDialogButtonBox::NoButton); + + std::string title_string = prequest.strDZeel; + std::replace( title_string.begin(), title_string.end(), '\n', ' '); + if (title_string.length() > 140) { + title_string = title_string.substr(0, 140); + title_string.append("..."); + } + ui->title->setText(QString::fromStdString(title_string)); +} + +void CommunityFundDisplayPaymentRequest::click_buttonBoxVote(QAbstractButton *button) +{ + //cast the vote + bool duplicate = false; + + if (ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::YesRole) + { + CFund::VotePaymentRequest(prequest.hash.ToString(), true, duplicate); + refresh(); + } + else if(ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::NoRole) + { + CFund::VotePaymentRequest(prequest.hash.ToString(), false, duplicate); + refresh(); + } + else if(ui->buttonBoxVote->buttonRole(button) == QDialogButtonBox::RejectRole) + { + CFund::RemoveVotePaymentRequest(prequest.hash.ToString()); + refresh(); + } + else { + refresh(); + return; + } +} + +void CommunityFundDisplayPaymentRequest::click_pushButtonDetails() +{ + CommunityFundDisplayPaymentRequestDetailed dlg(this, prequest); + dlg.exec(); + refresh(); +} + +CommunityFundDisplayPaymentRequest::~CommunityFundDisplayPaymentRequest() +{ + delete ui; +} diff --git a/src/qt/communityfunddisplaypaymentrequest.h b/src/qt/communityfunddisplaypaymentrequest.h new file mode 100644 index 000000000..e36e1d82d --- /dev/null +++ b/src/qt/communityfunddisplaypaymentrequest.h @@ -0,0 +1,32 @@ +#ifndef COMMUNITYFUNDDISPLAYPAYMENTREQUEST_H +#define COMMUNITYFUNDDISPLAYPAYMENTREQUEST_H + +#include +#include +#include "consensus/cfund.h" +#include "wallet/wallet.h" + +namespace Ui { +class CommunityFundDisplayPaymentRequest; +} + +class CommunityFundDisplayPaymentRequest : public QWidget +{ + Q_OBJECT + +public: + CommunityFundDisplayPaymentRequest(QWidget *parent = 0, CFund::CPaymentRequest prequest = CFund::CPaymentRequest()); + void refresh(); + ~CommunityFundDisplayPaymentRequest(); + +private: + Ui::CommunityFundDisplayPaymentRequest *ui; + CFund::CPaymentRequest prequest; + CWallet *wallet; + +public Q_SLOTS: + void click_buttonBoxVote(QAbstractButton *button); + void click_pushButtonDetails(); +}; + +#endif // COMMUNITYFUNDDISPLAYPAYMENTREQUEST_H diff --git a/src/qt/communityfunddisplaypaymentrequestdetailed.cpp b/src/qt/communityfunddisplaypaymentrequestdetailed.cpp new file mode 100644 index 000000000..d642dd450 --- /dev/null +++ b/src/qt/communityfunddisplaypaymentrequestdetailed.cpp @@ -0,0 +1,217 @@ +#include "communityfunddisplaypaymentrequestdetailed.h" +#include "ui_communityfunddisplaypaymentrequestdetailed.h" +#include "communityfundpage.h" +#include "main.h" +#include +#include +#include "wallet/wallet.h" +#include "base58.h" + +CommunityFundDisplayPaymentRequestDetailed::CommunityFundDisplayPaymentRequestDetailed(QWidget *parent, CFund::CPaymentRequest prequest) : + QDialog(parent), + ui(new Ui::CommunityFundDisplayPaymentRequestDetailed), + prequest(prequest) +{ + ui->setupUi(this); + + //connect ui elements to functions + connect(ui->buttonBoxYesNoVote_2, SIGNAL(clicked( QAbstractButton*)), this, SLOT(click_buttonBoxYesNoVote(QAbstractButton*))); + connect(ui->pushButtonClose_2, SIGNAL(clicked()), this, SLOT(reject())); + + //update labels + setPrequestLabels(); + + // Shade in yes/no buttons is user has voted + // If the prequest is pending and not prematurely expired (ie can be voted on): + if (prequest.fState == CFund::NIL && prequest.GetState().find("expired") == string::npos) { + // Get prequest votes list + auto it = std::find_if( vAddedPaymentRequestVotes.begin(), vAddedPaymentRequestVotes.end(), + [&prequest](const std::pair& element){ return element.first == prequest.hash.ToString();} ); + if (it != vAddedPaymentRequestVotes.end()) { + if (it->second) { + // Payment Request was voted yes, shade in yes button and unshade no button + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + } + else { + // Payment Request was noted no, shade in no button and unshade yes button + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + } + } + else { + // Payment Request was not voted on, reset shades of both buttons + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + + } + } + + //hide ui voting elements on prequests which are not allowed vote states + if(!prequest.CanVote()) + { + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::NoButton); + } +} + +void CommunityFundDisplayPaymentRequestDetailed::setPrequestLabels() const +{ + // Title + ui->labelPaymentRequestTitle->setText(QString::fromStdString(prequest.strDZeel)); + + // Amount + string amount; + amount = wallet->formatDisplayAmount(prequest.nAmount); + ui->labelPrequestAmount->setText(QString::fromStdString(amount)); + + // Status + ui->labelPrequestStatus->setText(QString::fromStdString(prequest.GetState())); + + // Yes Votes + ui->labelPrequestYes->setText(QString::fromStdString(std::to_string(prequest.nVotesYes))); + + // No Votes + ui->labelPrequestNo->setText(QString::fromStdString(std::to_string(prequest.nVotesNo))); + + // Payment Request Hash + ui->labelPrequestHash->setText(QString::fromStdString(prequest.hash.ToString())); + + // Transaction Block Hash + ui->labelPrequestTransactionBlockHash->setText(QString::fromStdString(prequest.blockhash.ToString())); + + // Transaction Hash + ui->labelPrequestTransactionHash->setText(QString::fromStdString(prequest.txblockhash.ToString())); + + // Version Number + ui->labelPrequestVersionNo->setText(QString::fromStdString(std::to_string(prequest.nVersion))); + + // Voting Cycle + ui->labelPrequestVotingCycle->setText(QString::fromStdString(std::to_string(prequest.nVotingCycle))); + + // Proposal Hash + ui->labelPrequestProposalHash->setText(QString::fromStdString(prequest.proposalhash.ToString())); + + // Payment Hash + ui->labelPrequestPaymentHash->setText(QString::fromStdString(prequest.paymenthash.ToString())); + + // Link + ui->labelPrequestLink->setText(QString::fromStdString("https://www.navexplorer.com/community-fund/payment-request/" + prequest.hash.ToString())); + + // Hide ability to vote is the status is expired + std::string status = ui->labelPrequestStatus->text().toStdString(); + if (status.find("expired") != string::npos) { + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::NoButton); + } + + // Expiry + uint64_t proptime = 0; + if (mapBlockIndex.count(prequest.blockhash) > 0) { + proptime = mapBlockIndex[prequest.blockhash]->GetBlockTime(); + } + + // If prequest is pending show voting cycles left + if (prequest.fState == CFund::NIL) { + std::string duration_title = "Voting period finishes in: "; + std::string duration = std::to_string(Params().GetConsensus().nCyclesPaymentRequestVoting-prequest.nVotingCycle) + " voting cycles"; + ui->labelPrequestExpiryTitle->setText(QString::fromStdString(duration_title)); + ui->labelPrequestExpiry->setText(QString::fromStdString(duration)); + } + + // If prequest is accepted, show when it was accepted + if (prequest.fState == CFund::ACCEPTED) { + std::string duration_title = "Accepted on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelPrequestExpiryTitle->setText(QString::fromStdString(duration_title)); + ui->labelPrequestExpiry->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + + // If prequest is rejected, show when it was rejected + if (prequest.fState == CFund::REJECTED) { + std::string expiry_title = "Rejected on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelPrequestExpiryTitle->setText(QString::fromStdString(expiry_title)); + ui->labelPrequestExpiry->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + + // If expired show when it expired + if (prequest.fState == CFund::EXPIRED || status.find("expired") != string::npos) { + if (prequest.fState == CFund::EXPIRED) { + std::string expiry_title = "Expired on: "; + std::time_t t = static_cast(proptime); + std::stringstream ss; + ss << std::put_time(std::gmtime(&t), "%c %Z"); + ui->labelPrequestExpiryTitle->setText(QString::fromStdString(expiry_title)); + ui->labelPrequestExpiry->setText(QString::fromStdString(ss.str().erase(10, 9))); + } + else { + std::string expiry_title = "Expires: "; + std::string expiry = "At end of voting period"; + ui->labelPrequestExpiryTitle->setText(QString::fromStdString(expiry_title)); + ui->labelPrequestExpiry->setText(QString::fromStdString(expiry)); + } + } + + //set hyperlink for navcommunity proposal view + ui->labelPrequestLink->setTextFormat(Qt::RichText); + ui->labelPrequestLink->setText("labelPrequestLink->text() + "\">" + ui->labelPrequestLink->text() + ""); + ui->labelPrequestLink->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->labelPrequestLink->setOpenExternalLinks(true); + + // If prequest is pending, hide the transaction hash + if (prequest.fState == CFund::NIL) { + ui->labelPrequestTransactionBlockHashTitle->setVisible(false); + ui->labelPrequestTransactionBlockHash->setVisible(false); + } + + // If the prequest is not accepted, hide the payment hash + if (prequest.fState != CFund::ACCEPTED) { + ui->labelPrequestPaymentHashTitle->setVisible(false); + ui->labelPrequestPaymentHash->setVisible(false); + } + + ui->labelPaymentRequestTitle->setText(QString::fromStdString(prequest.strDZeel.c_str())); + +} + +void CommunityFundDisplayPaymentRequestDetailed::click_buttonBoxYesNoVote(QAbstractButton *button) +{ + // Cast the vote + bool duplicate = false; + + if (ui->buttonBoxYesNoVote_2->buttonRole(button) == QDialogButtonBox::YesRole) + { + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_YES); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + CFund::VotePaymentRequest(prequest.hash.ToString(), true, duplicate); + } + else if(ui->buttonBoxYesNoVote_2->buttonRole(button) == QDialogButtonBox::NoRole) + { + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes|QDialogButtonBox::Cancel); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NO); + CFund::VotePaymentRequest(prequest.hash.ToString(), false, duplicate); + } + else if(ui->buttonBoxYesNoVote_2->buttonRole(button) == QDialogButtonBox::RejectRole) + { + ui->buttonBoxYesNoVote_2->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::Yes)->setStyleSheet(COLOR_VOTE_NEUTRAL); + ui->buttonBoxYesNoVote_2->button(QDialogButtonBox::No)->setStyleSheet(COLOR_VOTE_NEUTRAL); + CFund::RemoveVotePaymentRequest(prequest.hash.ToString()); + } + else { + return; + } +} + +CommunityFundDisplayPaymentRequestDetailed::~CommunityFundDisplayPaymentRequestDetailed() +{ + delete ui; +} diff --git a/src/qt/communityfunddisplaypaymentrequestdetailed.h b/src/qt/communityfunddisplaypaymentrequestdetailed.h new file mode 100644 index 000000000..a948cb319 --- /dev/null +++ b/src/qt/communityfunddisplaypaymentrequestdetailed.h @@ -0,0 +1,32 @@ +#ifndef COMMUNITYFUNDDISPLAYPAYMENTREQUESTDETAILED_H +#define COMMUNITYFUNDDISPLAYPAYMENTREQUESTDETAILED_H + +#include +#include "consensus/cfund.h" +#include "wallet/wallet.h" +#include +#include + +namespace Ui { +class CommunityFundDisplayPaymentRequestDetailed; +} + +class CommunityFundDisplayPaymentRequestDetailed : public QDialog +{ + Q_OBJECT + +public: + explicit CommunityFundDisplayPaymentRequestDetailed(QWidget *parent = 0, CFund::CPaymentRequest prequest = CFund::CPaymentRequest()); + ~CommunityFundDisplayPaymentRequestDetailed(); + +private: + Ui::CommunityFundDisplayPaymentRequestDetailed *ui; + CFund::CPaymentRequest prequest; + CWallet *wallet; + void setPrequestLabels() const; + +public Q_SLOTS: + void click_buttonBoxYesNoVote(QAbstractButton *button); +}; + +#endif // COMMUNITYFUNDDISPLAYPAYMENTREQUESTDETAILED_H diff --git a/src/qt/communityfundpage.cpp b/src/qt/communityfundpage.cpp new file mode 100644 index 000000000..b35ef8bdf --- /dev/null +++ b/src/qt/communityfundpage.cpp @@ -0,0 +1,399 @@ +#include "communityfundpage.h" +#include "forms/ui_communityfundpage.h" +#include "communityfundpage.moc" + +#include "main.h" +#include "txdb.h" +#include "wallet/wallet.h" +#include +#include +#include +#include + +#include "communityfunddisplay.h" +#include "communityfunddisplaypaymentrequest.h" +#include "communityfundcreateproposaldialog.h" +#include "communityfundcreatepaymentrequestdialog.h" + +CommunityFundPage::CommunityFundPage(const PlatformStyle *platformStyle, QWidget *parent) : + QWidget(parent), + ui(new Ui::CommunityFundPage), + clientModel(0), + walletModel(0), + flag(CFund::NIL), + viewing_proposals(true), + viewing_voted(false), + viewing_unvoted(false) +{ + ui->setupUi(this); + + // Hide horizontal scrollArea scroll bar + ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + connect(ui->pushButtonProposals, SIGNAL(clicked()), this, SLOT(click_pushButtonProposals())); + connect(ui->pushButtonPaymentRequests, SIGNAL(clicked()), this, SLOT(click_pushButtonPaymentRequests())); + + // Enable selection of pushButtonProposals by default + ui->pushButtonProposals->setStyleSheet("QPushButton { background-color: #DBE0E8; }"); + ui->pushButtonPaymentRequests->setStyleSheet("QPushButton { background-color: #EDF0F3; }"); + + // Connect push buttons to functions + connect(ui->radioButtonAll, SIGNAL(clicked()), this, SLOT(click_radioButtonAll())); + connect(ui->radioButtonYourVote, SIGNAL(clicked()), this, SLOT(click_radioButtonYourVote())); + connect(ui->radioButtonPending, SIGNAL(clicked()), this, SLOT(click_radioButtonPending())); + connect(ui->radioButtonAccepted, SIGNAL(clicked()), this, SLOT(click_radioButtonAccepted())); + connect(ui->radioButtonRejected, SIGNAL(clicked()), this, SLOT(click_radioButtonRejected())); + connect(ui->radioButtonExpired, SIGNAL(clicked()), this, SLOT(click_radioButtonExpired())); + connect(ui->radioButtonNoVote, SIGNAL(clicked()), this, SLOT(click_radioButtonNoVote())); + connect(ui->pushButtonCreateProposal, SIGNAL(clicked()), this , SLOT(click_pushButtonCreateProposal())); + connect(ui->pushButtonCreatePaymentRequest, SIGNAL(clicked()), this, SLOT(click_pushButtonCreatePaymentRequest())); + + click_radioButtonPending(); + refresh(false, true); +} + +void CommunityFundPage::setWalletModel(WalletModel *model) +{ + this->walletModel = model; + flag = CFund::NIL; + viewing_voted = false; + viewing_unvoted = true; + refresh(false, true); + ui->radioButtonNoVote->setChecked(true); +} + +void CommunityFundPage::refreshTab() +{ + refresh(ui->radioButtonAll->isChecked(), viewing_proposals); +} + +void CommunityFundPage::deleteChildWidgets(QLayoutItem *item) { + QLayout *layout = item->layout(); + if (layout) + { + int itemCount = ui->gridLayout->count(); + for (int index = 0; index < itemCount; index++) + { + deleteChildWidgets(ui->gridLayout->itemAt(index)); + } + } + delete item->widget(); +} + +void CommunityFundPage::reset() +{ + for (int index = ui->gridLayout->count() - 1; index >= 0; --index) + { + int row, column, rowSpan, columnSpan; + ui->gridLayout->getItemPosition(index, &row, &column, &rowSpan, &columnSpan); + QLayoutItem *item = ui->gridLayout->takeAt(index); + deleteChildWidgets(item); + delete item; + } +} + +void CommunityFundPage::append(QWidget* widget) +{ + int index = ui->gridLayout->count(); + int row, column, rowSpan, columnSpan; + ui->gridLayout->getItemPosition(index, &row, &column, &rowSpan, &columnSpan); + row = int(index/2); + column = index%2; + ui->gridLayout->addWidget(widget, row, column); +} + +void CommunityFundPage::refresh(bool all, bool proposal) +{ + reset(); + + // Format avaliable amount in the community fund + string available; + available = wallet->formatDisplayAmount(pindexBestHeader->nCFSupply); + ui->labelAvailableAmount->setText(QString::fromStdString(available)); + + // Format locked amount in the community fund + string locked; + locked = wallet->formatDisplayAmount(pindexBestHeader->nCFLocked); + ui->labelLockedAmount->setText(QString::fromStdString(locked)); + + { + int64_t spent_nav = 0; + std::vector vec; + if(pblocktree->GetPaymentRequestIndex(vec)) + { + BOOST_FOREACH(const CFund::CPaymentRequest& prequest, vec) + { + if(prequest.fState == CFund::ACCEPTED) + { + spent_nav = spent_nav + prequest.nAmount; + } + } + + string spent; + spent = wallet->formatDisplayAmount(spent_nav); + ui->labelSpentAmount->setText(QString::fromStdString(spent)); + } + } + + // Propulate proposal grid + if (proposal) { + std::vector vec; + if(pblocktree->GetProposalIndex(vec)) + { + BOOST_FOREACH(const CFund::CProposal proposal, vec) { + // If wanting to view all proposals + if (all) { + append(new CommunityFundDisplay(0, proposal)); + } + else { + // If the filter is set to my vote, filter to only pending proposals which have been voted for + if (viewing_voted) + { + if (proposal.fState == CFund::NIL && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") == string::npos) + { + auto it = std::find_if( vAddedProposalVotes.begin(), vAddedProposalVotes.end(), + [&proposal](const std::pair& element){ return element.first == proposal.hash.ToString();} ); + if (it != vAddedProposalVotes.end()) + { + append(new CommunityFundDisplay(0, proposal)); + } else + { + continue; + } + } + else + { + continue; + } + } + // If the filter is set to no vote, filter to only pending proposals which have been not been voted for yet + else if (viewing_unvoted) + { + if (proposal.fState == CFund::NIL && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") == string::npos) + { + auto it = std::find_if( vAddedProposalVotes.begin(), vAddedProposalVotes.end(), + [&proposal](const std::pair& element){ return element.first == proposal.hash.ToString();} ); + if (it != vAddedProposalVotes.end()) + { + continue; + } else + { + append(new CommunityFundDisplay(0, proposal)); + } + } + else + { + continue; + } + } + else + { + // If the flag is expired, be sure to display proposals without the expired state if they have expired before the end of the voting cycle + if (proposal.fState != CFund::EXPIRED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") != string::npos && flag == CFund::EXPIRED) + { + append(new CommunityFundDisplay(0, proposal)); + } + // If the proposal is accepted and waiting for funds or the end of the voting cycle, show in the accepted filter + if (flag == CFund::ACCEPTED && proposal.fState != CFund::ACCEPTED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("accepted") != string::npos) { + append(new CommunityFundDisplay(0, proposal)); + } + // If the proposal is rejected and waiting for funds or the end of the voting cycle, show in the rejected filter + if (flag == CFund::REJECTED && proposal.fState != CFund::REJECTED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("rejected") != string::npos) { + append(new CommunityFundDisplay(0, proposal)); + } + // Display proposals with the appropriate flag and have not expired before the voting cycle has ended + if (proposal.fState != flag || ((flag != CFund::EXPIRED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("expired") != string::npos) || + (flag != CFund::ACCEPTED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("accepted") != string::npos) || + (flag != CFund::REJECTED && proposal.GetState(pindexBestHeader->GetBlockTime()).find("rejected") != string::npos))) + continue; + append(new CommunityFundDisplay(0, proposal)); + } + } + } + } + } + else + { //Payment request listings + std::vector vec; + if(pblocktree->GetPaymentRequestIndex(vec)) + { + BOOST_FOREACH(const CFund::CPaymentRequest& prequest, vec) { + // If wanting to view all prequests + if (all) + { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + else + { + // If the filter is set to my vote, filter to only pending prequests which have been voted for + if (viewing_voted) + { + if (prequest.fState == CFund::NIL && prequest.GetState().find("expired") == string::npos) + { + auto it = std::find_if( vAddedPaymentRequestVotes.begin(), vAddedPaymentRequestVotes.end(), + [&prequest](const std::pair& element){ return element.first == prequest.hash.ToString();} ); + if (it != vAddedPaymentRequestVotes.end()) + { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } else + { + continue; + } + } + else + { + continue; + } + } + // If the filter is set to no vote, filter to only pending prequests which have not been voted for yet + else if (viewing_unvoted) + { + if (prequest.fState == CFund::NIL && prequest.GetState().find("expired") == string::npos) + { + auto it = std::find_if( vAddedPaymentRequestVotes.begin(), vAddedPaymentRequestVotes.end(), + [&prequest](const std::pair& element){ return element.first == prequest.hash.ToString();} ); + if (it != vAddedPaymentRequestVotes.end()) + { + continue; + } else + { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + } + else + { + continue; + } + } + else + { + // If the flag is expired, be sure to display prequests without the expired state if they have expired before the end of the voting cycle + if (prequest.fState != CFund::EXPIRED && prequest.GetState().find("expired") != string::npos && flag == CFund::EXPIRED) + { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + // If the prequest is accepted and waiting for funds or the end of the voting cycle, show in the accepted filter + if (flag == CFund::ACCEPTED && prequest.fState != CFund::ACCEPTED && prequest.GetState().find("accepted") != string::npos) { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + // If the prequest is rejected and waiting for funds or the end of the voting cycle, show in the rejected filter + if (flag == CFund::REJECTED && prequest.fState != CFund::REJECTED && prequest.GetState().find("rejected") != string::npos) { + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + // Display prequests with the appropriate flag and have not expired before the voting cycle has ended + if (prequest.fState != flag || ((flag != CFund::EXPIRED && prequest.GetState().find("expired") != string::npos) || + (flag != CFund::ACCEPTED && prequest.GetState().find("accepted") != string::npos) || + (flag != CFund::REJECTED && prequest.GetState().find("rejected") != string::npos))) + continue; + append(new CommunityFundDisplayPaymentRequest(0, prequest)); + } + } + } + } + } +} + +void CommunityFundPage::click_pushButtonProposals() +{ + QFont font = ui->pushButtonProposals->property("font").value(); + + ui->pushButtonProposals->setStyleSheet("QPushButton { background-color: #DBE0E8; }"); + ui->pushButtonPaymentRequests->setStyleSheet("QPushButton { background-color: #EDF0F3; }"); + + QFont f(font.family(), font.pointSize(), QFont::Bold); + ui->pushButtonProposals->setFont(f); + ui->pushButtonPaymentRequests->setFont(f); + + viewing_proposals = true; + refresh(ui->radioButtonAll->isChecked(), viewing_proposals); +} + +void CommunityFundPage::click_pushButtonPaymentRequests() +{ + QFont font = ui->pushButtonPaymentRequests->property("font").value(); + + ui->pushButtonProposals->setStyleSheet("QPushButton { background-color: #EDF0F3; }"); + ui->pushButtonPaymentRequests->setStyleSheet("QPushButton { background-color: #DBE0E8; }"); + + QFont f(font.family(), font.pointSize(), QFont::Bold); + ui->pushButtonProposals->setFont(f); + ui->pushButtonPaymentRequests->setFont(f); + + viewing_proposals = false; + refresh(ui->radioButtonAll->isChecked(), viewing_proposals); +} + +void CommunityFundPage::click_radioButtonAll() +{ + flag = CFund::NIL; + viewing_voted = false; + viewing_unvoted = false; + refresh(true, viewing_proposals); +} + +void CommunityFundPage::click_radioButtonYourVote() +{ + flag = CFund::NIL; + viewing_voted = true; + viewing_unvoted = false; + refresh(false, viewing_proposals); +} + +void CommunityFundPage::click_radioButtonPending() +{ + flag = CFund::NIL; + viewing_voted = false; + viewing_unvoted = false; + refresh(false, viewing_proposals); +} + +void CommunityFundPage::click_radioButtonAccepted() +{ + flag = CFund::ACCEPTED; + viewing_voted = false; + viewing_unvoted = false; + refresh(false, viewing_proposals); +} + +void CommunityFundPage::click_radioButtonRejected() +{ + flag = CFund::REJECTED; + viewing_voted = false; + viewing_unvoted = false; + refresh(false, viewing_proposals); +} + +void CommunityFundPage::click_radioButtonExpired() +{ + flag = CFund::EXPIRED; + viewing_voted = false; + viewing_unvoted = false; + refresh(false, viewing_proposals); +} + +void CommunityFundPage::click_pushButtonCreateProposal() +{ + CommunityFundCreateProposalDialog dlg(this); + dlg.exec(); + refresh(ui->radioButtonAll->isChecked(), viewing_proposals); +} + +void CommunityFundPage::click_pushButtonCreatePaymentRequest() +{ + CommunityFundCreatePaymentRequestDialog dlg(this); + dlg.exec(); + refresh(ui->radioButtonAll->isChecked(), viewing_proposals); +} + +void CommunityFundPage::click_radioButtonNoVote() +{ + flag = CFund::NIL; + viewing_voted = false; + viewing_unvoted = true; + refresh(false, viewing_proposals); +} + +CommunityFundPage::~CommunityFundPage() +{ + delete ui; +} diff --git a/src/qt/communityfundpage.h b/src/qt/communityfundpage.h new file mode 100644 index 000000000..f9869978c --- /dev/null +++ b/src/qt/communityfundpage.h @@ -0,0 +1,68 @@ +#ifndef COMMUNITYFUNDPAGE_H +#define COMMUNITYFUNDPAGE_H + +#include "communityfundpage.moc" +#include "consensus/cfund.h" +#include "wallet/wallet.h" + +#include +#include +#include +#include +#include + +// Color constants +#define COLOR_VOTE_YES "background-color: #90ee90;" +#define COLOR_VOTE_NO "background-color: #f08080;" +#define COLOR_VOTE_NEUTRAL "background-color: #f3f4f6;" + +class ClientModel; +class TransactionFilterProxy; +class TxViewDelegate; +class PlatformStyle; +class WalletModel; + +namespace Ui { +class CommunityFundPage; +} + +class CommunityFundPage : public QWidget +{ + Q_OBJECT + +public: + explicit CommunityFundPage(const PlatformStyle *platformStyle, QWidget *parent = 0); + void setWalletModel(WalletModel *walletModel); + void refreshTab(); + void append(QWidget* widget); + void refresh(bool all, bool proposal); + void deleteChildWidgets(QLayoutItem *item); + void reset(); + ~CommunityFundPage(); + +private: + Ui::CommunityFundPage *ui; + ClientModel *clientModel; + WalletModel *walletModel; + CFund::flags flag; + CWallet *wallet; + bool viewing_proposals; + bool viewing_voted; + bool viewing_unvoted; + +private Q_SLOTS: + void click_pushButtonProposals(); + void click_pushButtonPaymentRequests(); + void click_radioButtonAll(); + void click_radioButtonYourVote(); + void click_radioButtonPending(); + void click_radioButtonAccepted(); + void click_radioButtonRejected(); + void click_radioButtonExpired(); + void click_pushButtonCreateProposal(); + void click_pushButtonCreatePaymentRequest(); + void click_radioButtonNoVote(); + +}; + +#endif // COMMUNITYFUNDPAGE_H diff --git a/src/qt/communityfundsuccessdialog.cpp b/src/qt/communityfundsuccessdialog.cpp new file mode 100644 index 000000000..8b58c45ba --- /dev/null +++ b/src/qt/communityfundsuccessdialog.cpp @@ -0,0 +1,41 @@ +#include "communityfundsuccessdialog.h" +#include "ui_communityfundsuccessdialog.h" +#include + +CommunityFundSuccessDialog::CommunityFundSuccessDialog(uint256 hash, QWidget *parent, CFund::CProposal* proposal) : + QDialog(parent), + ui(new Ui::CommunityFundSuccessDialog), + proposal(proposal), + prequest(0) +{ + ui->setupUi(this); + connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(reject())); + + // Generate label for proposal + ui->label->setTextFormat(Qt::RichText); + ui->label->setText(QString::fromStdString("You can now view your proposal in the core wallet or on the navexplorer once the next block has been broadcast")); + ui->label->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->label->setOpenExternalLinks(true); +} + +CommunityFundSuccessDialog::CommunityFundSuccessDialog(uint256 hash, QWidget *parent, CFund::CPaymentRequest* prequest) : + QDialog(parent), + ui(new Ui::CommunityFundSuccessDialog), + proposal(0), + prequest(prequest) +{ + ui->setupUi(this); + connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(reject())); + + // Generate label for payment request + ui->labelTitle->setText(QString("Created Payment Request Successfully")); + ui->label->setTextFormat(Qt::RichText); + ui->label->setText(QString::fromStdString("You can now view your payment request in the core wallet or on the navexplorer once the next block has been broadcast")); + ui->label->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->label->setOpenExternalLinks(true); +} + +CommunityFundSuccessDialog::~CommunityFundSuccessDialog() +{ + delete ui; +} diff --git a/src/qt/communityfundsuccessdialog.h b/src/qt/communityfundsuccessdialog.h new file mode 100644 index 000000000..d02fa9192 --- /dev/null +++ b/src/qt/communityfundsuccessdialog.h @@ -0,0 +1,28 @@ +#ifndef COMMUNITYFUNDSUCCESSDIALOG_H +#define COMMUNITYFUNDSUCCESSDIALOG_H + +#include +#include +#include +#include "../consensus/cfund.h" + +namespace Ui { +class CommunityFundSuccessDialog; +} + +class CommunityFundSuccessDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CommunityFundSuccessDialog(uint256 hash, QWidget *parent = 0, CFund::CPaymentRequest* prequest = 0); + explicit CommunityFundSuccessDialog(uint256 hash, QWidget *parent = 0, CFund::CProposal* proposal = 0); + ~CommunityFundSuccessDialog(); + +private: + Ui::CommunityFundSuccessDialog *ui; + CFund::CProposal* proposal; + CFund::CPaymentRequest* prequest; +}; + +#endif // COMMUNITYFUNDSUCCESSDIALOG_H diff --git a/src/qt/forms/cfund_voting.cpp b/src/qt/forms/cfund_voting.cpp deleted file mode 100644 index cf39cb73c..000000000 --- a/src/qt/forms/cfund_voting.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "cfund_voting.h" - -#include "txdb.h" -#include "consensus/cfund.h" -#include "main.h" - -CFund_Voting::CFund_Voting(QWidget *parent, bool fPaymentRequests) : - QDialog(parent), - ui(new Ui::CFund_Voting), - fSettings(fPaymentRequests) -{ - ui->setupUi(this); - - connect(ui->closeBtn, SIGNAL(clicked(bool)), this, SLOT(closeDialog())); - connect(ui->voteyesBtn, SIGNAL(clicked(bool)), this, SLOT(voteYes())); - connect(ui->votenoBtn, SIGNAL(clicked(bool)), this, SLOT(voteNo())); - connect(ui->stopvotingBtn, SIGNAL(clicked(bool)), this, SLOT(stopVoting())); - connect(ui->viewdetailsBtn, SIGNAL(clicked(bool)), this, SLOT(viewDetails())); - connect(ui->switchBtn, SIGNAL(clicked(bool)), this, SLOT(switchView())); - connect(ui->votingyesList, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(selectedFromYes(QListWidgetItem*))); - connect(ui->votingnoList, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(selectedFromNo(QListWidgetItem*))); - connect(ui->notvotingList, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(selectedFromNotVoting(QListWidgetItem*))); - Refresh(); -} - -void CFund_Voting::closeDialog() { - close(); -} - -void CFund_Voting::voteYes() { - if (selected == "") - return; - bool d = false; - if (!fSettings) { - CFund::VoteProposal(selected.toStdString(), true, d); - } else { - CFund::VotePaymentRequest(selected.toStdString(), true, d); - } - setSelection(""); - Refresh(); -} - -void CFund_Voting::voteNo() { - if (selected == "") - return; - bool d = false; - if (!fSettings) { - CFund::VoteProposal(selected.toStdString(), false, d); - } else { - CFund::VotePaymentRequest(selected.toStdString(), false, d); - } - setSelection(""); - Refresh(); -} - -void CFund_Voting::stopVoting() { - if (selected == "") - return; - if (!fSettings) { - CFund::RemoveVoteProposal(selected.toStdString()); - } else { - CFund::RemoveVotePaymentRequest(selected.toStdString()); - } - setSelection(""); - Refresh(); -} - -void CFund_Voting::viewDetails() { - if (selected == "") - return; - QString link = QString("https://www.navexplorer.com/community-fund/") + (fSettings ? QString("payment-request") : QString("proposal")) + QString("/") + selected; - QDesktopServices::openUrl(QUrl(link)); -} - -void CFund_Voting::switchView() { - setSelection(""); - fSettings = !fSettings; - Refresh(); -} - -void CFund_Voting::selectedFromYes(QListWidgetItem* item) { - ui->notvotingList->clearSelection(); - ui->votingnoList->clearSelection(); - - setSelection(item->data(1).toString()); - ui->voteyesBtn->setEnabled(false); -} - -void CFund_Voting::selectedFromNo(QListWidgetItem* item) { - ui->notvotingList->clearSelection(); - ui->votingyesList->clearSelection(); - - setSelection(item->data(1).toString()); - ui->votenoBtn->setEnabled(false); -} - -void CFund_Voting::selectedFromNotVoting(QListWidgetItem* item) { - ui->votingnoList->clearSelection(); - ui->votingyesList->clearSelection(); - - setSelection(item->data(1).toString()); - ui->stopvotingBtn->setEnabled(false); -} - -void CFund_Voting::setSelection(QString selection) { - selected = selection; - enableDisableButtons(); -} - -void CFund_Voting::enableDisableButtons() { - - if(selected == "") { - ui->voteyesBtn->setEnabled(false); - ui->votenoBtn->setEnabled(false); - ui->stopvotingBtn->setEnabled(false); - ui->viewdetailsBtn->setEnabled(false); - } else { - ui->viewdetailsBtn->setEnabled(true); - ui->voteyesBtn->setEnabled(true); - ui->votenoBtn->setEnabled(true); - ui->stopvotingBtn->setEnabled(true); - } -} - -void CFund_Voting::Refresh() -{ - setWindowTitle(tr("Community Fund: ") + (fSettings ? tr("Payment Requests") : tr("Proposals"))); - - ui->votingnoList->clear(); - ui->votingyesList->clear(); - ui->notvotingList->clear(); - ui->switchBtn->setText(fSettings ? tr("Switch to Proposal View") : tr("Switch to Payment Request View")); - ui->viewdetailsBtn->setText(fSettings ? tr("View Payment Request Details") : tr("View Proposal Details")); - ui->windowMainTitle->setText(fSettings ? tr("Payment Request Voting") : tr("Proposal Voting")); - - enableDisableButtons(); - - int nCount = 0; - - { - std::vector vec; - if(pblocktree->GetProposalIndex(vec)) - { - BOOST_FOREACH(const CFund::CProposal& proposal, vec) { - if (proposal.fState != CFund::NIL) - continue; - QListWidget* whereToAdd = ui->notvotingList; - auto it = std::find_if( vAddedProposalVotes.begin(), vAddedProposalVotes.end(), - [&proposal](const std::pair& element){ return element.first == proposal.hash.ToString();} ); - if (it != vAddedProposalVotes.end()) { - if (it->second) - whereToAdd = ui->votingyesList; - else - whereToAdd = ui->votingnoList; - } - if (!fSettings) - { - QListWidgetItem *item = new QListWidgetItem(QString::fromStdString(proposal.strDZeel), whereToAdd); - item->setData(1, QString::fromStdString(proposal.hash.ToString())); - } else { - if (whereToAdd == ui->notvotingList) - nCount++; - } - } - } - } - - { - std::vector vec; - if(pblocktree->GetPaymentRequestIndex(vec)) - { - BOOST_FOREACH(const CFund::CPaymentRequest& prequest, vec) { - if (prequest.fState != CFund::NIL) - continue; - QListWidget* whereToAdd = ui->notvotingList; - auto it = std::find_if( vAddedPaymentRequestVotes.begin(), vAddedPaymentRequestVotes.end(), - [&prequest](const std::pair& element){ return element.first == prequest.hash.ToString();} ); - if (it != vAddedPaymentRequestVotes.end()) { - if (it->second) - whereToAdd = ui->votingyesList; - else - whereToAdd = ui->votingnoList; - } - if (fSettings) - { - QListWidgetItem *item = new QListWidgetItem(QString::fromStdString(prequest.strDZeel), whereToAdd); - item->setData(1, QString::fromStdString(prequest.hash.ToString())); - } else { - if (whereToAdd == ui->notvotingList) - nCount++; - } - } - } - } - - if (nCount > 0) - ui->otherViewLabel->setText(fSettings ? tr("There are %1 new Proposals on the other view.").arg(nCount) : tr("There are %1 new Payment Requests on the other view.").arg(nCount)); - else - ui->otherViewLabel->setText(""); - -} - -CFund_Voting::~CFund_Voting() -{ - delete ui; -} diff --git a/src/qt/forms/cfund_voting.h b/src/qt/forms/cfund_voting.h deleted file mode 100644 index 93dce8202..000000000 --- a/src/qt/forms/cfund_voting.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef CFUND_VOTING_H -#define CFUND_VOTING_H -#include "ui_cfund_voting.h" - -#include -#include -#include - -namespace Ui { -class CFund_Voting; -} - -class CFund_Voting : public QDialog -{ - Q_OBJECT - -public: - explicit CFund_Voting(QWidget *parent = 0, bool fPaymentRequests = false); - ~CFund_Voting(); - - void Refresh(); - - QString selected; - -public Q_SLOTS: - void closeDialog(); - void voteYes(); - void voteNo(); - void stopVoting(); - void viewDetails(); - void switchView(); - void selectedFromYes(QListWidgetItem* item); - void selectedFromNo(QListWidgetItem* item); - void selectedFromNotVoting(QListWidgetItem* item); - void enableDisableButtons(); - void setSelection(QString selection); - -private: - Ui::CFund_Voting *ui; - bool fSettings; -}; - -#endif // CFUND_VOTING_H diff --git a/src/qt/forms/cfund_voting.ui b/src/qt/forms/cfund_voting.ui deleted file mode 100644 index a078f3e3c..000000000 --- a/src/qt/forms/cfund_voting.ui +++ /dev/null @@ -1,205 +0,0 @@ - - - CFund_Voting - - - - 0 - 0 - 622 - 498 - - - - Dialog - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - .PingFang TC - 18 - - - - Proposal Voting - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - No vote selected: - - - - - - - Qt::ClickFocus - - - - - - - Voting for: - - - - - - - Qt::ClickFocus - - - - - - - Voting against: - - - - - - - Qt::ClickFocus - - - - - - - - - - - false - - - View Proposal Details - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Stop Voting - - - - - - - false - - - Vote Yes - - - - - - - false - - - Vote No - - - - - - - - - - - Switch to Payment Request View - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Close - - - - - - - - - - diff --git a/src/qt/forms/communityfundcreatepaymentrequestdialog.ui b/src/qt/forms/communityfundcreatepaymentrequestdialog.ui new file mode 100644 index 000000000..8235bb161 --- /dev/null +++ b/src/qt/forms/communityfundcreatepaymentrequestdialog.ui @@ -0,0 +1,158 @@ + + + CommunityFundCreatePaymentRequestDialog + + + + 0 + 0 + 400 + 300 + + + + Create Payment Request + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + Create Payment Request + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Proposal Hash: + + + + + + + + + + + 75 + true + + + + Requested Amount (NAV): + + + + + + + + + + + 75 + true + + + + Description: + + + + + + + + + + false + + + + + + + 0 + + + + + Submit Payment Request + + + + + + + Close + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + NavCoinAmountField + QLineEdit +
navcoinamountfield.h
+ 1 +
+ + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+ + QValidatedPlainTextEdit + QPlainTextEdit +
qvalidatedplaintextedit.h
+
+
+ + +
diff --git a/src/qt/forms/communityfundcreateproposaldialog.ui b/src/qt/forms/communityfundcreateproposaldialog.ui new file mode 100644 index 000000000..f07b520d8 --- /dev/null +++ b/src/qt/forms/communityfundcreateproposaldialog.ui @@ -0,0 +1,246 @@ + + + CommunityFundCreateProposalDialog + + + + 0 + 0 + 400 + 400 + + + + Create Proposal + + + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + Create Proposal + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + NavCoin Address: + + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Requested Amount (NAV): + + + + + + + + + + + 75 + true + + + + Description: + + + + + + + + + + false + + + + + + + + 75 + true + + + + Proposal Duration: + + + + + + + + + + + 0 + + + + + + + Days + + + Qt::AlignCenter + + + + + + + + + 0 + + + + + + + + Hours + + + Qt::AlignCenter + + + + + + + + + 0 + + + + + + + + Minutes + + + Qt::AlignCenter + + + + + + + + + + + + + Create Proposal + + + + + + + Close + + + + + + + + 8 + + + + By submitting the proposal a X NAV deduction will occur from your wallet + + + true + + + + + + + + + + + + NavCoinAmountField + QLineEdit +
navcoinamountfield.h
+ 1 +
+ + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+ + QValidatedPlainTextEdit + QPlainTextEdit +
qvalidatedplaintextedit.h
+
+ + QValidatedSpinBox + QSpinBox +
qvalidatedspinbox.h
+
+
+ + +
diff --git a/src/qt/forms/communityfunddisplay.ui b/src/qt/forms/communityfunddisplay.ui new file mode 100644 index 000000000..a3c206632 --- /dev/null +++ b/src/qt/forms/communityfunddisplay.ui @@ -0,0 +1,274 @@ + + + CommunityFundDisplay + + + + 0 + 0 + 433 + 260 + + + + + 0 + 0 + + + + + 433 + 260 + + + + + 433 + 260 + + + + + 433 + 433 + + + + Form + + + + + + + 0 + 0 + + + + + 433 + 433 + + + + + 433 + 433 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 400 + 50 + + + + + 0 + 0 + + + + + 11 + 75 + true + + + + Proposal Title + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByMouse + + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Status: + + + + + + + + 433 + 433 + + + + + 10 + + + + pending + + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + NAV Requested: + + + + + + + + 10 + + + + 100 NAV + + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Expires In: + + + + + + + + 10 + + + + 100 Days 100 Hours 100 Minutes + + + + + + + + + + + + 10 + + + + Qt::RightToLeft + + + QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + + 10 + + + + View Detail + + + + + + + + + + + + + + + diff --git a/src/qt/forms/communityfunddisplaydetailed.ui b/src/qt/forms/communityfunddisplaydetailed.ui new file mode 100644 index 000000000..b65dabe53 --- /dev/null +++ b/src/qt/forms/communityfunddisplaydetailed.ui @@ -0,0 +1,777 @@ + + + CommunityFundDisplayDetailed + + + + 0 + 0 + 740 + 497 + + + + + 0 + 0 + + + + + 740 + 497 + + + + Proposal Details + + + + + + + 0 + 0 + + + + + 16777215 + 100 + + + + + 11 + 75 + true + + + + Proposal Title + + + true + + + false + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Amount: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 NAV + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Fee: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 NAV + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Address: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + NfQJDyPrJ1DzyQQ29jQyewhS5qT3x3TMTG + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Proposal Duration: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 Days 100 Minutes 100 Seconds + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Expires In: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 Days 100 Minutes 100 Seconds + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Status: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + pending + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Number of Yes Votes: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 Yes + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Number of No Votes: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 No + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Transaction Block Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 95dbb71cfa4b67b258b34c1489e11e96955e1a9f26dd58a19f63417a37bce5d4 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Transaction Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 2da711320aa9e83b91f6e4111898abc0214fdb347623a5b2286d3caf33c1e8dd + + + Qt::TextSelectableByMouse + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + + 10 + 75 + true + + + + Proposal Hash + + + + + + + 9d486795bf6d90198b336dc354aa17f109f75cfa5536684b594f1d0c7f0f0981 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Version Number: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 2 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Voting Cycle Number: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Link to Proposal: + + + Qt::NoTextInteraction + + + + + + + https://navcommunity.net/view-proposal/95dbb71cfa4b67b258b34c1489e11e96955e1a9f26dd58a19f63417a37bce5d4 + + + true + + + true + + + Qt::TextBrowserInteraction + + + + + + + + + + + Qt::RightToLeft + + + QDialogButtonBox::Cancel|QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + + + + diff --git a/src/qt/forms/communityfunddisplaypaymentrequest.ui b/src/qt/forms/communityfunddisplaypaymentrequest.ui new file mode 100644 index 000000000..b81b0ca80 --- /dev/null +++ b/src/qt/forms/communityfunddisplaypaymentrequest.ui @@ -0,0 +1,224 @@ + + + CommunityFundDisplayPaymentRequest + + + + 0 + 0 + 433 + 260 + + + + + 0 + 0 + + + + + 433 + 260 + + + + + 433 + 260 + + + + Form + + + + + + + 0 + 0 + + + + + 433 + 433 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 10 + 400 + 50 + + + + + 400 + 50 + + + + + 11 + 75 + true + + + + Payment Reqest Title + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + 10 + 60 + 391 + 171 + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Status: + + + + + + + pending + + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + NAV Requested + + + + + + + 100 NAV + + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Expires In: + + + + + + + 100 Days 100 Hours 100 Minutes + + + + + + + + + + + Qt::RightToLeft + + + QDialogButtonBox::Cancel|QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + View Details + + + + + + + + title + + labelRequested + + + + + + + + + diff --git a/src/qt/forms/communityfunddisplaypaymentrequestdetailed.ui b/src/qt/forms/communityfunddisplaypaymentrequestdetailed.ui new file mode 100644 index 000000000..4ea168447 --- /dev/null +++ b/src/qt/forms/communityfunddisplaypaymentrequestdetailed.ui @@ -0,0 +1,742 @@ + + + CommunityFundDisplayPaymentRequestDetailed + + + + 0 + 0 + 740 + 497 + + + + + 0 + 0 + + + + + 740 + 497 + + + + Payment Request Details + + + + + 10 + 10 + 722 + 83 + + + + + 0 + 0 + + + + + 16777215 + 100 + + + + + 11 + 75 + true + + + + Payment Request Title + + + true + + + false + + + + + + 10 + 90 + 722 + 400 + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Amount: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 100 NAV + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Status: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + pending + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Number of Yes Votes: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 1000 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Number of No Votes: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 1000 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Payment Request Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 9d486795bf6d90198b336dc354aa17f109f75cfa5536684b594f1d0c7f0f0981 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Transaction Block Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 9d486795bf6d90198b336dc354aa17f109f75cfa5536684b594f1d0c7f0f0981 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Transaction Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 9d486795bf6d90198b336dc354aa17f109f75cfa5536684b594f1d0c7f0f0981 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Version Number: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 2 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Voting Cycle Number: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 0 + + + Qt::TextSelectableByMouse + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + + 10 + 75 + true + + + + Expires in: + + + + + + + 1 Voting Cycle + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Proposal Hash: + + + Qt::NoTextInteraction + + + + + + + + 10 + + + + 2da711320aa9e83b91f6e4111898abc0214fdb347623a5b2286d3caf33c1e8dd + + + Qt::TextSelectableByMouse + + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + + 10 + 75 + true + + + + Payment Hash: + + + + + + + 9d486795bf6d90198b336dc354aa17f109f75cfa5536684b594f1d0c7f0f0981 + + + Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 10 + 75 + true + + + + Link to Payment Request: + + + Qt::NoTextInteraction + + + + + + + https://navcommunity.net/view-proposal/95dbb71cfa4b67b258b34c1489e11e96955e1a9f26dd58a19f63417a37bce5d4 + + + true + + + true + + + Qt::TextBrowserInteraction + + + + + + + + + + + Qt::RightToLeft + + + QDialogButtonBox::Cancel|QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + + + diff --git a/src/qt/forms/communityfundpage.ui b/src/qt/forms/communityfundpage.ui new file mode 100644 index 000000000..499d2595a --- /dev/null +++ b/src/qt/forms/communityfundpage.ui @@ -0,0 +1,646 @@ + + + CommunityFundPage + + + + 0 + 0 + 979 + 690 + + + + Form + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Maximum + + + + 40 + 15 + + + + + + + + + + + + + 70 + 17 + + + + + 10 + 75 + true + + + + Available: + + + + + + + + 70 + 17 + + + + + 10 + 75 + true + + + + Locked: + + + + + + + + 70 + 17 + + + + + 10 + 75 + true + + + + Spent: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + + + 1000 + 17 + + + + + 10 + + + + 100 NAV + + + + + + + + 1000 + 17 + + + + + 10 + + + + 100 NAV + + + + + + + + 1000 + 17 + + + + + 10 + + + + 100 NAV + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 0 + 20 + + + + + + + + + 130 + 30 + + + + + 130 + 30 + + + + Proposals + + + + 35 + 16 + + + + false + + + true + + + false + + + + + + + + 130 + 30 + + + + + 130 + 30 + + + + Payment Requests + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 0 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 235 + 20 + + + + + + + + + + + + + 16777215 + 20 + + + + All + + + + 25 + 25 + + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 16777215 + 20 + + + + Your Vote + + + + 25 + 25 + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 16777215 + 20 + + + + No Vote + + + + 25 + 25 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 16777215 + 20 + + + + Pending + + + + 25 + 25 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 16777215 + 20 + + + + Accepted + + + + 25 + 25 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 16777215 + 20 + + + + Rejected + + + + 25 + 25 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + Expired + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 300 + 20 + + + + + + + + + 170 + 30 + + + + + 16777215 + 30 + + + + Create Proposal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 170 + 30 + + + + + 16777215 + 30 + + + + Create Payment Request + + + + + + + + + true + + + + + 0 + 0 + 903 + 534 + + + + + 0 + 0 + + + + + + + QLayout::SetMaximumSize + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + diff --git a/src/qt/forms/communityfundsuccessdialog.ui b/src/qt/forms/communityfundsuccessdialog.ui new file mode 100644 index 000000000..fbbb03971 --- /dev/null +++ b/src/qt/forms/communityfundsuccessdialog.ui @@ -0,0 +1,158 @@ + + + CommunityFundSuccessDialog + + + + 0 + 0 + 351 + 190 + + + + + 0 + 0 + + + + + 351 + 190 + + + + + 351 + 190 + + + + Success + + + + + -1 + -1 + 351 + 190 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 10 + 0 + 341 + 51 + + + + + + + + 16777215 + 50 + + + + + 11 + 75 + true + + + + Created Proposal Successfully + + + true + + + + + + + + + 10 + 50 + 341 + 91 + + + + + + + You can view your created proposal in the core wallet or at www.url.com + + + true + + + + + + + + + 0 + 140 + 351 + 51 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + + + diff --git a/src/qt/forms/moc_cfund_voting.cpp b/src/qt/forms/moc_cfund_voting.cpp deleted file mode 100644 index e7767bc0b..000000000 --- a/src/qt/forms/moc_cfund_voting.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** Meta object code from reading C++ file 'cfund_voting.h' -** -** -** WARNING! All changes made in this file will be lost! -*****************************************************************************/ - -#include "qt/forms/cfund_voting.h" -#include -#include -#if !defined(Q_MOC_OUTPUT_REVISION) -#error "The header file 'cfund_voting.h' doesn't include ." -#elif Q_MOC_OUTPUT_REVISION != 67 -#error "This file was generated using the moc from 5.10.0. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -QT_BEGIN_MOC_NAMESPACE -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED -struct qt_meta_stringdata_CFund_Voting_t { - QByteArrayData data[13]; - char stringdata0[150]; -}; -#define QT_MOC_LITERAL(idx, ofs, len) \ - Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ - qptrdiff(offsetof(qt_meta_stringdata_CFund_Voting_t, stringdata0) + ofs \ - - idx * sizeof(QByteArrayData)) \ - ) -static const qt_meta_stringdata_CFund_Voting_t qt_meta_stringdata_CFund_Voting = { - { -QT_MOC_LITERAL(0, 0, 12), // "CFund_Voting" -QT_MOC_LITERAL(1, 13, 11), // "closeDialog" -QT_MOC_LITERAL(2, 25, 0), // "" -QT_MOC_LITERAL(3, 26, 7), // "voteYes" -QT_MOC_LITERAL(4, 34, 6), // "voteNo" -QT_MOC_LITERAL(5, 41, 10), // "stopVoting" -QT_MOC_LITERAL(6, 52, 11), // "viewDetails" -QT_MOC_LITERAL(7, 64, 10), // "switchView" -QT_MOC_LITERAL(8, 75, 15), // "selectedFromYes" -QT_MOC_LITERAL(9, 91, 16), // "QListWidgetItem*" -QT_MOC_LITERAL(10, 108, 4), // "item" -QT_MOC_LITERAL(11, 113, 14), // "selectedFromNo" -QT_MOC_LITERAL(12, 128, 21) // "selectedFromNotVoting" - - }, - "CFund_Voting\0closeDialog\0\0voteYes\0" - "voteNo\0stopVoting\0viewDetails\0switchView\0" - "selectedFromYes\0QListWidgetItem*\0item\0" - "selectedFromNo\0selectedFromNotVoting" -}; -#undef QT_MOC_LITERAL - -static const uint qt_meta_data_CFund_Voting[] = { - - // content: - 7, // revision - 0, // classname - 0, 0, // classinfo - 9, 14, // methods - 0, 0, // properties - 0, 0, // enums/sets - 0, 0, // constructors - 0, // flags - 0, // signalCount - - // slots: name, argc, parameters, tag, flags - 1, 0, 59, 2, 0x0a /* Public */, - 3, 0, 60, 2, 0x0a /* Public */, - 4, 0, 61, 2, 0x0a /* Public */, - 5, 0, 62, 2, 0x0a /* Public */, - 6, 0, 63, 2, 0x0a /* Public */, - 7, 0, 64, 2, 0x0a /* Public */, - 8, 1, 65, 2, 0x0a /* Public */, - 11, 1, 68, 2, 0x0a /* Public */, - 12, 1, 71, 2, 0x0a /* Public */, - - // slots: parameters - QMetaType::Void, - QMetaType::Void, - QMetaType::Void, - QMetaType::Void, - QMetaType::Void, - QMetaType::Void, - QMetaType::Void, 0x80000000 | 9, 10, - QMetaType::Void, 0x80000000 | 9, 10, - QMetaType::Void, 0x80000000 | 9, 10, - - 0 // eod -}; - -void CFund_Voting::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) -{ - if (_c == QMetaObject::InvokeMetaMethod) { - CFund_Voting *_t = static_cast(_o); - Q_UNUSED(_t) - switch (_id) { - case 0: _t->closeDialog(); break; - case 1: _t->voteYes(); break; - case 2: _t->voteNo(); break; - case 3: _t->stopVoting(); break; - case 4: _t->viewDetails(); break; - case 5: _t->switchView(); break; - case 6: _t->selectedFromYes((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break; - case 7: _t->selectedFromNo((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break; - case 8: _t->selectedFromNotVoting((*reinterpret_cast< QListWidgetItem*(*)>(_a[1]))); break; - default: ; - } - } -} - -const QMetaObject CFund_Voting::staticMetaObject = { - { &QDialog::staticMetaObject, qt_meta_stringdata_CFund_Voting.data, - qt_meta_data_CFund_Voting, qt_static_metacall, nullptr, nullptr} -}; - - -const QMetaObject *CFund_Voting::metaObject() const -{ - return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; -} - -void *CFund_Voting::qt_metacast(const char *_clname) -{ - if (!_clname) return nullptr; - if (!strcmp(_clname, qt_meta_stringdata_CFund_Voting.stringdata0)) - return static_cast(this); - return QDialog::qt_metacast(_clname); -} - -int CFund_Voting::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QDialog::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 9) - qt_static_metacall(this, _c, _id, _a); - _id -= 9; - } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { - if (_id < 9) - *reinterpret_cast(_a[0]) = -1; - _id -= 9; - } - return _id; -} -QT_WARNING_POP -QT_END_MOC_NAMESPACE diff --git a/src/qt/forms/sendcommunityfunddialog.ui b/src/qt/forms/sendcommunityfunddialog.ui new file mode 100644 index 000000000..aff666b0c --- /dev/null +++ b/src/qt/forms/sendcommunityfunddialog.ui @@ -0,0 +1,348 @@ + + + SendCommunityFundDialog + + + + 0 + 0 + 473 + 211 + + + + + 0 + 0 + + + + Confirm Proposal Details + + + + + + QLayout::SetMinimumSize + + + + + + 10 + 75 + true + + + + Are you sure you would like to create the following proposal? + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 9 + 75 + true + + + + Address: + + + + + + + + 0 + 0 + + + + NfQJDyPrJ1DzyQQ29jQyewhS5qT3x3TMTG + + + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 75 + true + + + + Proposal Hash: + + + + + + + + 0 + 0 + + + + 1337 + + + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 75 + true + + + + Requested Amount: + + + + + + + 100 NAV / 100 EUR / 100 USD / 100 BTC + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 75 + true + + + + Description: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Placeholder Description + + + true + + + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 75 + true + + + + Proposal Duration: + + + + + + + 100 Days 100 Hours 100 Minutes + + + + + + + + + + + + 8 + + + + By submitting the proposal a X NAV deduction will occur from your wallet + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 2 + 20 + + + + + + + + Yes + + + + + + + + + + + + diff --git a/src/qt/locale/navcoin_en.ts b/src/qt/locale/navcoin_en.ts index 79ed793c4..252daae47 100755 --- a/src/qt/locale/navcoin_en.ts +++ b/src/qt/locale/navcoin_en.ts @@ -323,97 +323,6 @@ - - CFund_Voting - - - Dialog - - - - - - Proposal Voting - - - - - No vote selected: - - - - - Voting for: - - - - - Voting against: - - - - - - View Proposal Details - - - - - Stop Voting - - - - - Vote Yes - - - - - Vote No - - - - - - Switch to Payment Request View - - - - - Close - - - - - Community Fund: - - - - - Payment Requests - - - - - Proposals - - - - - Switch to Proposal View - - - - - View Payment Request Details - - - - - Payment Request Voting - - - CoinControlDialog @@ -1194,7 +1103,7 @@ - There are new proposals or payment requests in the Community Fund.<br><br>As a staker it's important to engage in the voting process.<br><br>Please cast your vote using the voting dialog! + There are new proposals or payment requests in the Community Fund.<br><br>As a staker it's important to engage in the voting process.<br><br>Please cast your vote using the Community Fund tab! diff --git a/src/qt/navcoin.qrc b/src/qt/navcoin.qrc index 1a061aaad..e4708cf78 100755 --- a/src/qt/navcoin.qrc +++ b/src/qt/navcoin.qrc @@ -64,6 +64,9 @@ res/icons/transaction_ns.png res/icons/transaction_s.png res/icons/transaction_hover.png + res/icons/community_fund_hover.png + res/icons/community_fund_s.png + res/icons/community_fund_ns.png res/fonts/roboto.ttf res/fonts/robotoregular.ttf res/fonts/source.ttf diff --git a/src/qt/navcoingui.cpp b/src/qt/navcoingui.cpp index 02fbf9a64..83ba08e0e 100755 --- a/src/qt/navcoingui.cpp +++ b/src/qt/navcoingui.cpp @@ -17,7 +17,6 @@ #include "notificator.h" #include "openuridialog.h" #include "optionsdialog.h" -#include "forms/cfund_voting.h" #include "optionsmodel.h" #include "platformstyle.h" #include "rpcconsole.h" @@ -81,6 +80,7 @@ #include #include #include +#include #if QT_VERSION < 0x050000 #include @@ -582,9 +582,6 @@ void NavCoinGUI::createMenuBar() } connect(currency,SIGNAL(triggered(QAction*)),this,SLOT(onCurrencySelection(QAction*))); settings->addAction(updatePriceAction); - QMenu *cfund = appMenuBar->addMenu(tr("&Community Fund")); - cfund->addAction(cfundProposalsAction); - cfund->addAction(cfundPaymentRequestsAction); } settings->addAction(optionsAction); @@ -665,7 +662,14 @@ void NavCoinGUI::createToolBars() topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); - + topMenu5 = new QPushButton(); + walletFrame->menuLayout->addWidget(topMenu5); + topMenu5->setFixedSize(215,94); + topMenu5->setObjectName("topMenu5"); + connect(topMenu5, SIGNAL(clicked()), this, SLOT(gotoCommunityFundPage())); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); QWidget *topMenu = new QWidget(); topMenu->setObjectName("topMenu"); topMenu->setStyleSheet( @@ -886,27 +890,18 @@ void NavCoinGUI::cfundProposalsClicked() { if(!clientModel || !clientModel->getOptionsModel()) return; - - CFund_Voting dlg(this, false); - dlg.exec(); } void NavCoinGUI::cfundProposalsOpen(bool fMode) { if(!clientModel || !clientModel->getOptionsModel()) return; - - CFund_Voting dlg(this, fMode); - dlg.exec(); } void NavCoinGUI::cfundPaymentRequestsClicked() { if(!clientModel || !clientModel->getOptionsModel()) return; - - CFund_Voting dlg(this, true); - dlg.exec(); } void NavCoinGUI::aboutClicked() @@ -961,6 +956,9 @@ void NavCoinGUI::gotoOverviewPage() topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); if (walletFrame) walletFrame->gotoOverviewPage(); } @@ -977,10 +975,33 @@ void NavCoinGUI::gotoHistoryPage() "#topMenu3:hover { border-image: url(:/icons/menu_receive_hover) 0 0 0 0 stretch stretch; border: 0px; }"); topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_s) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); historyAction->setChecked(true); if (walletFrame) walletFrame->gotoHistoryPage(); } +void NavCoinGUI::gotoCommunityFundPage() +{ + topMenu1->setStyleSheet( + "#topMenu1 { border-image: url(:/icons/menu_home_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu1:hover { border-image: url(:/icons/menu_home_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu2->setStyleSheet( + "#topMenu2 { border-image: url(:/icons/menu_send_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu2:hover { border-image: url(:/icons/menu_send_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu3->setStyleSheet( + "#topMenu3 { border-image: url(:/icons/menu_receive_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu3:hover { border-image: url(:/icons/menu_receive_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu4->setStyleSheet( + "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_s) 0 0 0 0 stretch stretch; border: 0px; }"); + historyAction->setChecked(true); + if (walletFrame) walletFrame->gotoCommunityFundPage(); +} + void NavCoinGUI::gotoReceiveCoinsPage() { topMenu1->setStyleSheet( @@ -994,6 +1015,9 @@ void NavCoinGUI::gotoReceiveCoinsPage() topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); receiveCoinsAction->setChecked(true); if (walletFrame) walletFrame->gotoReceiveCoinsPage(); } @@ -1011,6 +1035,9 @@ void NavCoinGUI::gotoRequestPaymentPage() topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); receiveCoinsAction->setChecked(true); if (walletFrame) walletFrame->gotoRequestPaymentPage(); } @@ -1028,6 +1055,9 @@ void NavCoinGUI::gotoSendCoinsPage(QString addr) topMenu4->setStyleSheet( "#topMenu4 { border-image: url(:/icons/menu_transaction_ns) 0 0 0 0 stretch stretch; border: 0px; }" "#topMenu4:hover { border-image: url(:/icons/menu_transaction_hover) 0 0 0 0 stretch stretch; border: 0px; }"); + topMenu5->setStyleSheet( + "#topMenu5 { border-image: url(:/icons/menu_community_fund_ns) 0 0 0 0 stretch stretch; border: 0px; }" + "#topMenu5:hover { border-image: url(:/icons/menu_community_fund_hover) 0 0 0 0 stretch stretch; border: 0px; }"); sendCoinsAction->setChecked(true); if (walletFrame) walletFrame->gotoSendCoinsPage(addr); } @@ -1842,13 +1872,14 @@ void NavCoinGUI::updateStakingStatus() } if ((fFoundPaymentRequest || fFoundProposal) && !this->fDontShowAgain && (this->lastDialogShown + (60*60*24)) < GetTimeNow()) { QCheckBox *cb = new QCheckBox("Don't show this notification again until wallet is restarted."); - QMessageBox msgbox; + QMessageBox msgbox(this); + msgbox.setWindowTitle("Community Fund Update"); QString sWhat = fFoundProposal && fFoundPaymentRequest ? tr("Proposals and Payment Requests") : (fFoundProposal ? tr("Proposals") : tr("Payment Requests")); - msgbox.setText(tr("There are new %1 in the Community Fund.

As a staker it's important to engage in the voting process.

Please cast your vote using the voting dialog!").arg(sWhat)); - msgbox.setIcon(QMessageBox::Icon::Warning); + msgbox.setText(tr("There are new %1 in the Community Fund.

As a staker it's important to engage in the voting process.

Please cast your vote using the Community Fund tab!").arg(sWhat)); + msgbox.setIcon(QMessageBox::Icon::Information); msgbox.setCheckBox(cb); QAbstractButton* pButtonInfo = msgbox.addButton(tr("Read about the Community Fund"), QMessageBox::YesRole); - QAbstractButton* pButtonOpen = msgbox.addButton(tr("Open Voting Window"), QMessageBox::YesRole); + QAbstractButton* pButtonOpen = msgbox.addButton(tr("Open Community Fund"), QMessageBox::YesRole); QAbstractButton* pButtonClose = msgbox.addButton(tr("Close"), QMessageBox::RejectRole); pButtonClose->setVisible(false); this->lastDialogShown = GetTimeNow(); @@ -1862,7 +1893,7 @@ void NavCoinGUI::updateStakingStatus() } if (msgbox.clickedButton()==pButtonOpen) { - cfundProposalsOpen(fFoundPaymentRequest); + gotoCommunityFundPage(); } if (msgbox.clickedButton()==pButtonInfo) { QString link = QString("https://navcoin.org/en/community-fund/"); diff --git a/src/qt/navcoingui.h b/src/qt/navcoingui.h index 559735a6d..bba20ed67 100755 --- a/src/qt/navcoingui.h +++ b/src/qt/navcoingui.h @@ -130,10 +130,11 @@ class NavCoinGUI : public QMainWindow QAction *unlockWalletAction; QAction *lockWalletAction; QAction *toggleStakingAction; - QPushButton *topMenu1; - QPushButton *topMenu2; - QPushButton *topMenu3; - QPushButton *topMenu4; + QPushButton *topMenu1; // Home + QPushButton *topMenu2; // Send + QPushButton *topMenu3; // Recieve + QPushButton *topMenu4; // Transaction History + QPushButton *topMenu5; // Community Fund QSystemTrayIcon *trayIcon; QMenu *trayIconMenu; @@ -223,6 +224,8 @@ private Q_SLOTS: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); + /** Switch to community fund page*/ + void gotoCommunityFundPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ diff --git a/src/qt/qvalidatedplaintextedit.cpp b/src/qt/qvalidatedplaintextedit.cpp new file mode 100644 index 000000000..aced0dead --- /dev/null +++ b/src/qt/qvalidatedplaintextedit.cpp @@ -0,0 +1,56 @@ +#include "qvalidatedplaintextedit.h" +#include "guiconstants.h" + +QValidatedPlainTextEdit::QValidatedPlainTextEdit(QWidget *parent): + QPlainTextEdit(parent), + valid(true) +{ + connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); +} + +void QValidatedPlainTextEdit::setValid(bool valid) +{ + if(valid == this->valid) + return; + if(valid) + setStyleSheet(""); + else + setStyleSheet(STYLE_INVALID); + + this->valid = valid; +} + +void QValidatedPlainTextEdit::focusInEvent(QFocusEvent *evt) +{ + setValid(true); + QPlainTextEdit::focusInEvent(evt); +} + +void QValidatedPlainTextEdit::focusOutEvent(QFocusEvent *evt) +{ + QPlainTextEdit::focusOutEvent(evt); +} + + +void QValidatedPlainTextEdit::clear() +{ + setValid(true); + QPlainTextEdit::clear(); +} + +void QValidatedPlainTextEdit::setEnabled(bool enabled) +{ + if (!enabled) + setValid(true); + + QPlainTextEdit::setEnabled(enabled); +} + +bool QValidatedPlainTextEdit::isValid() +{ + if(toPlainText().length() >= 1024) + setValid(false); + else + setValid(true); + //Q_EMIT validationDidChange(this); +} diff --git a/src/qt/qvalidatedplaintextedit.h b/src/qt/qvalidatedplaintextedit.h new file mode 100644 index 000000000..c28db5ae7 --- /dev/null +++ b/src/qt/qvalidatedplaintextedit.h @@ -0,0 +1,35 @@ +#ifndef QVALIDATEDPLAINTEXTEDIT_H +#define QVALIDATEDPLAINTEXTEDIT_H + +#include +#include +#include + +class QValidatedPlainTextEdit : public QPlainTextEdit +{ +public: + explicit QValidatedPlainTextEdit(QWidget *parent); + void clear(); + void setCheckValidator(const QValidator *v); + bool isValid(); + +protected: + void focusInEvent(QFocusEvent *evt); + void focusOutEvent(QFocusEvent *evt); + +private: + bool valid; + +public Q_SLOTS: + void setValid(bool valid); + void setEnabled(bool enabled); + +//Q_SIGNALS: + //void validationDidChange(QPlainTextEdit *validatedLineEdit); + +private Q_SLOTS: + void markValid(); + void checkValidity(); +}; + +#endif // QVALIDATEDPLAINTEXTEDIT_H diff --git a/src/qt/qvalidatedspinbox.cpp b/src/qt/qvalidatedspinbox.cpp new file mode 100644 index 000000000..b27ea2036 --- /dev/null +++ b/src/qt/qvalidatedspinbox.cpp @@ -0,0 +1,50 @@ +#include "qvalidatedspinbox.h" +#include "guiconstants.h" +#include "skinize.h" + +#include + +QValidatedSpinBox::QValidatedSpinBox(QDialog *parent) : + QSpinBox(parent), + valid(true) +{ + connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); +} + +void QValidatedSpinBox::setValid(bool valid) +{ + if(valid == this->valid) + { + return; + } + + if(valid) + { + setStyleSheet(Skinize()); + } + else + { + setStyleSheet(STYLE_INVALID); + } + this->valid = valid; +} + +void QValidatedSpinBox::focusInEvent(QFocusEvent *evt) +{ + // Clear invalid flag on focus + setValid(true); + Q_EMIT clickedSpinBox(); + QSpinBox::focusInEvent(evt); +} + +void QValidatedSpinBox::markValid() +{ + // As long as a user is typing ensure we display state as valid + setValid(true); +} + +void QValidatedSpinBox::clear() +{ + setValid(true); + QSpinBox::clear(); +} diff --git a/src/qt/qvalidatedspinbox.h b/src/qt/qvalidatedspinbox.h new file mode 100644 index 000000000..e49e5e418 --- /dev/null +++ b/src/qt/qvalidatedspinbox.h @@ -0,0 +1,31 @@ +#ifndef QVALIDATEDSPINBOX_H +#define QVALIDATEDSPINBOX_H + +#include +#include + +class QValidatedSpinBox : public QSpinBox +{ + Q_OBJECT + +public: + QValidatedSpinBox(QDialog *parent); + void clear(); + +protected: + void focusInEvent(QFocusEvent *evt); + +private: + bool valid; + +public Q_SLOTS: + void setValid(bool valid); + +Q_SIGNALS: + void clickedSpinBox(); + +private Q_SLOTS: + void markValid(); +}; + +#endif // QVALIDATEDSPINBOX_H diff --git a/src/qt/res/icons/community_fund_hover.png b/src/qt/res/icons/community_fund_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..095478143de56cd89a541cc1878563d0f71aa0f2 GIT binary patch literal 7933 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 JYNglV{|5q7ldAv# literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/community_fund_ns.png b/src/qt/res/icons/community_fund_ns.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa3ab4d6c8a06894e09331b92811cb5794780c0 GIT binary patch literal 6921 zcmbVQ2T)UOmyR^03o0PeR4i2KB@_V#q$AR+f}urPAasa|fJlje5J4a!HS}Hrh=_uK zfDnoh0-sU>L;R*r;PZCg% z0){izbp|@V0Jlwth#EMcyY%vU4qoC8tl>ULcP{Mx=bq#VbLY6X~(b$ z#+?wwX&rsT;JMdN)^e)9(j}-YELL~(k4I$t{dP7M6B&QwnxaG-#lR!ce`z&*+V2K^ zFgNWUBmaw`tp$Ttl-DjymX|rK4it8!>k9I4NF^LHJbfeAS+#mZw`@%;+pse}%0A)O zD?{4kCbXtR&{HS!U}aS4(}&HS;Xg>@N?cD7Z}y_>VYCv4;`V}!e4}WFGaLfvv*KuI ztP;(f6H$fd<#cE~KqG!?dd9TY<a2GLU2@rN^hBn+aWEo}x?A31?~UCiC9YQo%4< zD|7GVP5fng%M2z`z$Ia6yJWH4Q)OE(puHlRS?_LPfh$ydYu(^HI`TbpJ3aG#Q$aGa z-xk_d>)s6`E)Bex*5#GixS7YsuQ0hN8!aL`C_@_YsO?|v`P$=BS>Zk1TG{k|xVN+n z8!+Kn>QmeRAvy#SuwIQ-luMo_)`-w!2G8|4TWm7;+%~Jcj)l|p-^r;kDcb5cSD%tJ zh4k+&Jq)z@uFOBj=4xf|SX)oYhD}L;-C5|Zl_8{C@lT|X70rkJ#=p2gSE&5oqG<`- zuPGNB+qL>B4vTX-i}}A8m#;mZshCb(*Zq39EpP9XwRa3D?yJ)ItA$d+%GU8YZCT^W zLQ;?JiZ*=Qwv71DJN~&1Dx~n*kiD~H5o)g=y0;otQ06c`?`yE|XU#n@Ge)hx(Sg$B z=D{a+KU%oc2s90=-o^E}(qp=bN<9MtZGfPr7bBo-^ojRBo7kjlu(!eu!w^{u}vM%z86n z)rneXw+boCeP!73^Qw)GZcvMRO$GF;O%o%$>n(Np>Q}^&7Ww|HAHNqcXi?B2{mk8|6@S??0kYe$T~M%_SU;7l z+V8C+#7)R(dAGM{5u|0Up@1~*8;eD9JaK5q&CSo@$oigziE%S-*P4s%#)3D78t;&J zTnHkAFCR6(l8SF5&u@--G-bVc z>mh`Bl>0*JMR{&(3rg!Wm@F%kSp7 z{1I~anqHU4{qo@TD{#X=Nc5ufHR9Em`Ym^}JaS(9z16Io33@6z7YaM0qrIkoRyO~` zoo_|OO1jA&Z}>8Ge(RiG;nd3j_@Cpr0jf)rV7Y}a$2=~saha2-NjJT*WH+G z)bpVidSQk&F}=|sC9x-OzMYN~YIRADQ^IhTcHsyqO~1@PeR$2O@JUZ?4gThC@!kcS z>x#vR%jf0_BwoqyrS55AV)%uXYF{@>3B@|~GkHvKkZnA48v35v7O(};i%l)^6?|Fb zJ)3w9&iO$3_bXG5c{N&3M!dTkL+o6D@%!?qfmbg0*E&OlZwoejUcQ-`^gSM@12xyd zb%k#C%q)M_mTTH+{JN2Nc{Ao!!(!OfkN7mRYeu}3r=6YFPW0M|TeNxbsF*WkV=-|j zb;jSSG&bjqOkb_h49(;)sC^S9r1cN~@YT?yX&WuArvq|DXm3rHtoEzomm$+AldR(|Er8fE?aY@Do<`bGZ47u1PQr2Vxb2FJnJ+tO!e zl+Sw89#90r1BF@@rDhlSG|8KS=wqIp-FIi48rJ)6n$@(EJ9W7~??&t`YVF0aD{@_W zR2=!%>s=n_XRc%Ba>O2eLGqFKrDs&ep*4O>T%GDvFj0HYIdI5XmBrNbY%{*Je`#Yi z2qz$IIx?B0KZYyM4)nhmJF(z%$4$e-k4d{0U5JcHTU9^{VP?;^NnB!KzBs=){<;0s zh;hQHsLSAWKu9n+8|dBz9iM#Ow-u!VR~UWo+4zG%l2=dcRB*xVK;Yu(06in^)3Y@6 zbPSxeYXaYaOBVyQtpo1(czHp*13-6RkVgTK$3j6K0q#P&dPb&J&)B#@AkJHQcQws} zCszn~AKr;m-Rm<__TNXj`JB!T1KJk=VI=+!dqxie{nLc1K%oCHIxZ0CpZ4?<4d}$qT7&-6XqZ8uf11X_Q=tE_ z|GU$_JN{pso;d&4BK^D5lc@iPNdM+kOA*G&&BL1KVC!l$ zpfhE%@6APfYQ*PZ%D{1fiT+|tu7=Qi)0_FGH-#(54SY|5p20(3ef>}~QD$jnRgcA% z*h>~USKrjz2yI(lT^(CoERKndy}-f%$-JJ%0HPb~X)Ke;NN}!xn~p-&x3#SVoYptX zH8qt);l{?&#ruZ8e0lNtR~1X=`wd{-%{zLkyzHX2G{wZkY#kjfB~htfcvicI8HPH{ z%*-46;U`a7Uj9IHDtxW!9!#ruz6Nmqd%X$xsk5rYQQ=*GL!CI_XtCG~li%NO1Y|}Q zJwoK2dPkjTSYhccUR5YdkSseq^(pqbWXHKDkAVDESG}V? z!)(IB!fM0~fHSa48^Nkf3{kKaf<2K&<6-Wd3oC)phYvN9@7*o*=#}elj7fOJ1H>T8 z6+byOWe(0BTUaP$ihlkCZz;z+IyaZEm3#IA%hOLbk!kt`>EmKt@wRq$ zxQ&gPl%9OxejN5n@k#V=Va?)wHFfp%1?A-u^P3?y>7y|BH2rIkTAT99%2I3b-UhFW zF_&?27nq`Lmu=~Q%{Q88C~s?1^YZo<6+nt*7<&5q*Dmmyt3XzqK9-jDF^U7IUmH7% z@m@D?ceP0$8yl-@YAOy^U7Zr1ic5}2^T-NU7c3V8>H$zUeWK@?dR=RQ^nnc3)YJxE zek2eau5mI(P*xiCg*hh)gq6Ls0YHdtZRNo3SB{50p09wW;+mY87%H`@tgEVe|3sk_)?DVRRJOkEXJlj~-^ySmnzr?B=CE*~S@38r z77Lr#?}Q*I_!;m6JH27{$TeDrmca5^2oL~u$pis&q-<9r2)>hLlwC4uz7Lg>--o(I z!kOIm!b;qxObp6NNts%8MV)4sQ&ADq!@^1FuCA_G<2ydxw-EaVJ{#Cy^L$;{RGD@+gk32I|A^`%+9tD=X!8G)erkezaV9JscwNtynyURUMqWo zKLG?#0ckytCwadNB?0S1XbZD)ir7vw!@LpiOM%$D>Yl|Sjz1plb>9YGZg9Gi{DU01 zt3sU>JT_Gou*x-k4YAQLFbmyUOkSOCD~*nhPH%7t32FYdi7_v^{?Hg(mKS=kwS;Ly z-g5d_24I@V{IhW;5-;_ov~j&F@seAlcc1aN2T*#VX~VPK$Zg8ZvE%U}@iua0lYypm zc4uejjp6m}>lkjw)5}(n)>4a;e&$%Oe@j|H`4!35o&8jL2eHZr}(q9V6k#)Y7q;! z(cKP3gXr7idAdj?jvP)b9XrQ)C=@!0$K#@zxq*Ai0e(XD6*yNH2Y}0iRV%Wyvt6>| zKFBEk0*cEJXD-Z{JV<;H6x4Vad7ND7MI|{MmxP3GFIyxck$nwbZQ=W7m5yyG!VsB@ z{r&w*2iqihl4a~?09^9Q$|8VgAZ1cd>J4MUR6D|{eedfnwy9|V#gAn$$;ru?L~d?w z{B)&p`Y490!z6Me^=g{5f=5bT;BaubIY`1{!`0COYN7ez>Xll# z@4tT425LaLPc>|(tPl=2-Sw%rYxEu+^^r#p1{IR(LMdWxG)TeQfz!C!+FE%D^Rw1& zmXI#SPO0-O4D-8`Y^W8$mn0I&=thHD*>Y+Kyg6;3k+`ssWphi?0hhu2M0-cNOkaV&mehs+yR00{q@|j zHTV~uZ7uYcqR(_d($`wI!K_aJYXI<_$rhgSc4!T*o?p4h!=p3`RnslUQSrBBWIhZH z-KYLyNBF8E;^X77ezOcWzMRuRJ#1kl2a55q0BuGrP2a=I%jnXjOOro;0w^{EXm)zq zQMa>~yer0=D9Xn+PAzu9n43wW{2Ov%F6;NrKW13{Av4La(bb!E$zNQ)%Wn+t9 zWD7gAM^dd%@3b<*c@uS@ALoFDF^-`dn{efcX?3h*IDL8)hs&$4msg8Cv}PAnAL)!` z-~KZpTVRGsYN#;8jjXLz0YoIHtUTc>Y*lpQ3t?gc6Ed|ZERd+P{gvBE2@w$y!8-0$ z*XG^WvT)+*6a}>FV0Gzag!tXtjIoSAMW+P9}%{ zEyva$KtsjNlVHufNhPZBNiD{uc27<_py{8%UEdaB+~rE*xo>$setcH|sas&C2NdK< zYfIDTZx4j<#K^`|^nSKeSM1rLaKbW?-IK!-0j&t9GlJv?w_67 z7wV1+xA((&d3nuDOprjY14M)@(Mg;Ox3d%2tyO9+DgyK^R9{a`8Liz_a$ZM=X0yFy zS|0@9ANSBuTL9rT;(Z?S^n?gQnkgw3qIzB6AHk{zD*z8Q4`i$CPLGSYKg!1ZC^1yW&&*T;4`F3x#k9A#&$hGK zUlc_fUQg?Hz1YE1?!~i_Qm_@|ryzM+}KWZiB?c2Anw+L-^KoZ8x?~96b zlkd%q^e(?x=K6k89AndZ%ycwx+Q)1-ESPyfKl{VxBIlon!GKKAzQS>hGcE{hzjNAK zh48Mt!j5`~ujsdE3iPW@=8j3J3f76>+FUW{`b-FLX!=Eo0dtW2U0w$>v|q4`^PKf zu_tm@M3e6=_T6d^I1;U8uB-8`wk~Vt+HLS2(GdD83)Fse0408r27^P3)4x3GokY|^ z)zLmp_S?Qh%h+#L$lUh{cYb|csXt*5#R!5t(wY8<>`zqPjPEAeO6R`jt8)0RJ3N0Ay3u#~EF+S#}}L18DnTBs>1# z3&&u!xuzSfFdrM~aDTIR9tKcTx5B;8az@)bJEFXay`*ihL~Bk?&eb5R7h0EDSy+^A zyaGsb22eetKYzXjnz`ak`0P~C)d)o|lWW4X&z^R5b!9>CnB=G?Lu}v=WG!MX#5!u* z>E)!Q{T8XJhBn@fcB!eU1H#oNX!SIR4X>aes(bc6(1;O7o9N8l&ziV%@}3-Z;EQXN zEqb!}n1@V8K+L{Xp=(Kwv0+MAcenB{4r{VHvOCY8H~`3V;^)YsSp61)w|3rrKwv?A zeSdgZ0ObOR*re~p5u~y5OmyVi>})TkFb$yEWJOCu2|xo=c|_fqHy{!(?@+dICU%}2 zfk8o~EiL$^bj-)15{Fm`(n9|`TWf3IBqFfhom~0C5gR=>y!zROfLhrk4niT2`KW`| ztgnC?vW}c*=G{EQX-$sq{VN_IZ(_{v#KgoT0t#T0E6Fbl3kw5|4nyc^p1CZA^6~MF zAQ6WyR4N(a1AdwhQ~)|+$A+Mn-_l}-MjSP-5?aQ$CZBm^9tHd7Z=N@k<5f$)yfs=_R0Ln0QvT{J4bVy5Hf_?KJ9n@Vlm?)PxVX82nup*U zfHCA`A8l4=fjQzrymmAI1y)vNcpwigEiLcGi^f9ikL>I;0B|>Q z&nU!HS4;PQ|6W{KN&cdHl?EhH#(oc?g^!DiD{N=213Feg!8HkSak(r+;(K83_;r`2 z6l+(R49Etcm3f;2x}P-16LWw3N=d@9io3#QFEnwC9vBArz4QR?ppWXvq*Nb9wqvna zHWmR?-!=4L5ukZxhbzonZ^Ts40+Z%H=DWB!#_jFxQM&YTl7*8KT2;VglXf-`fR(9Z zrBzEyi~KWS6Otlc2!XPiH%0U4kS37yZECFp&&doj6BeV_DE&xC->+vsSmQ zO`(SXma;00fbf6@zymS=>UerG`~DBp`TuX`{kzi>=l^Bo|8Jb04AlR1~!W zk5d=-vvD^NHxBMO5>gk7#iY3?b;S&ITpfK<${yK1F5x4H+aZfhd2e2YknK9%Yt#bq zv7_F8f-7Uw0u>8kza6Kg^Rs2pH$a~kHE|{ldw^EXs-{$Qaf*PvZi%Qx>oZ{fnscG$<kz5D==e4HKpoSm)*y7{?Y*VZvGGJnCw z4FGUMbRKJ%1`*b$Cw;B)4&B?tGY=xpb((Q#>gI^*zF*L!J?l2~2u!bum(u}`{HhmE z@}mx?sO%w0k6Z{*%{3`92E(LB~uQ-?^7kA;gEi933 z%#m&HZpO>>_BL^d|IRHKFOL1PyWD4GV`ZkPnbO-A631|tA6rr+8ZW6ef7Lg5%l`5F z)tKPsiaR>Nl*L=NP0#;mV|>8QvN2g*_zEJft!n*R9~ex zEZbfhSRh^+@)NUmf@iEmQ9>uXLUUmU z8_L@Lt=AeB*e1b_7kOnj%MGl$gv$0-wD1)oB((gL-^th673k~L?LcBn-fx2i zdnejB#dSR4T8qo_P1?x3B$d_@YVhI#e3<4n9hQR(SFbpcU!-=j0-@uVBe`67rn!-YYS8_>tRs|(`r)A`gtF|p2_wZ>L6LPxG2ktRKahm!*jxE+pLuRH;Pus7eJHS;p%c~ z+}!uAaj1vWYatDu-CHRp1B5A~+qZ{T;NM+Eoc|=Q@JF8<5%S01Z4Ncs7O=!X7j;2V=qcHfZy2&2pLL@4TMhklb z>Thgbdpl%_J1Et*>U%!m8RGM_C1}$ZUDgG$_8@@kJTk({s44xUKpY5Dnh5eWb(b4LPmLlz6=FaQ&N! zcK69Ub@>?E0(|2ue@eBT1LD3&vi2rn|=gC*P>i^q;;q4pvRS zNpG=h07%WP1%2WXF2~RJzUjycA#fk;=KJ1rhrvuItfm{~Q8eVOUv;jU=rsg}KUx0l z#a3x^SR-Fn>$7hfucVZ^u+5_iSIURtnQ|9*(~!Y?(=f>Up64c3^y#A{SNe#FZ!YY# z4kop{?&E9ewXzmmQXX=c5RvG;@Ja1>pw^w9$LcLjLIOK1=R&AUcu*%!@WT7PO$ieN z{}y^+F%>+f^kFK+ts^aKTL)&wA|LTag*)OXE@@WmV}+r(oE%hMpG?4Ul6k~6zBD{$ zb+D!(Odrysh%&cxe=0yMcwnE<@O;8O*u_#1In;BNws_E;6@m+$xAIePo*n=@pT-Y5 ziO7zclldUZ`Mte6O-TnK4wfJ$dFx_W(|Ac=QrzQkwJ*kn&%b91?mvEoFAHQN_mjYI z6|I<0HVXb37!k5+1OI=;CpHFi}-LE$R56#d(40@nRd z+E*L!hYi*A(fpX0l2VohTnzmCNvl1V(87)^LpKOhf$|9RBys*H?#T%` z&l24n9WinIGajY}gJR5k6}sxPs#=90%nIpSIz7Uq$uFooN6oIAP$!QMq8b$XQaAR+ zDE~k`B#)GmkmEJK<8y>5?B%HL-j@Zh3WaZhcZlMQSFKKa4qhLI*qJf*=HRutlEBiY zMF@Y|MlyXNl~r%aBa=TpegOm(<~r{V_h{KRsx4&u1i&mK8=g0tg`TZujzW7)3*aMn zJ>ja1`9{vpYPQYKjanM7q+ASI{`^-7Lzrq1hg%RFr&Zn*Vy~T^)+s(hZP2B#_G@X~ z$SgPF9d0M^5(w8Q<7uAs-A-1eD!ciGCH=MgH&S}3{CU_`a4cJ`ToF7Rox0B%&U14+ zQ_?XVl*SIUYmz1*O472D!r<$kh}_c|*W;*mIi(3AI(>J5BrNQknw$(egxs&gI`)l{Bw2zj z@)LHtR`!a)7$LXOh0zEw_$F}n>)N}r86LmmTeFzI#$aJn=mr8aeJh+abDkbH1|qvf z`LWl6q|jHptz{G`Hhq0>rPKrb%ICEr()xVbQ>2;vcLSUv442WDGn7Xf?t#RMw~|P0 z^<1{cVp5kTj)SVZ;pDy6^dxQ)nl&$ET{+wzY+xWO5t0%i2-cC*Dk&=)eT&t~P#HqS z15?Mmn{@18-d=O-LdjlWXc3#E<)C!W}Q(b3fhSEGU@cTZ<=RlMCbytLw zD2$%*9Sb3T&-5H0<-0@APGQC5(^aeC5~FWEYoJl*YV%`DOOBKfcfx!I>Z_vy7PgJ= zI5QteimcphAr=;do>7G)Pfwzg|40lF2MuqD*lp_W7FPD{Il0LRMAsKCKRrm!WYsMA znx!z4yo+6IMCD0cw7#u5CBoqgs@isfv5${2?veH0P>)*w0KasY4zCDRjd;YgnqxA1 z_sDJxzZ{6$D?gp9u}WR_QU9#lr0=WfqQPFe!0YJOZ>%@h420=4;Gq}%cg{f(&DVGeTCZk0xdZ& zjx=y{84q5G$=I;rd@iSXa#TMc*oxtMX*Kh!YD5OOU_?5t)?;n5-CvSnmGOCr*e zPQad=DNvs=Y*aOMFLNqTt}x6T{M{5H1Q&JnG&qt)nxdyRHiqheFBIxqcZ0O&gYO3J zN>@*NtSwcQlpO7J+GI7I-iJ4K0hjhXR^a^sij5~DUn;bL%Hvt6il&0WP0(7juQM=# zw6NeyQJ)NvbA6;L&kAFDb_e<$eC45)bUH%qlFbBPR((P_l|ySzcKOKxyCgYG!l zlK$nP?;R0p^;8kB77?|R+wm;iY^x4~dmAMox;6URT1z>|4_1~J-93)#%k09r*Q74ufBBnBvl{)R#8sOS%a`8h^^I zp>K{H$nF&iKCaiQc=faE)8>=hrvBW(8F&14+_B>H#Hy*UZ$>k_RJ8dlQ?8MLmiac596L5Dc_H8mGo^Ckfu@YI%W8K6urAk9*~c7a|yUjRp6Gl zRlw&Y84CV&dnQnx+_CMlPK1yIe8Un4Bcn%`BP_VB}y89(^o|TWn`=K zo?DcZQ%Z3-4Ipw8sdmi`s2G%ON2Gn$^j8-&gKg&hI8)oOlwu2PqS(gC3){zVBG1%U zn^Nq!JF7|t(QH}wc9I+YMCFOel6Wq5xu7w;!}wCC1A44ny{?=I`Sp|>UE4Cjb&wzk zpi_tD<)S^(8fht(o0gP>r=MG$^n|$2(IIcnl(E-uHpIHCoIfiIGCYlNWR85u!SlN< zl19hZAK2>U@T8(Bc3*a5=-Zc&;nDp^Owg(s6!{>j*bVYvM0%SDSfd0dqtDqNj1~1? z5fg`^!RGimK}{$9g;MeKuj=&mkn_^3D-3-_s95ZIK(NL0YE6564N&G*uqrRm1@O^J z!{EaI1?7K-pMT@ppP>AArv1UT|AN5(N#Fm0=?`fBY5WtE|BdMnwEyq1{(28yp0oG+ zdA?m({L+C0+x+l&3PYj;|JrL0MEgRWe0-$m4iypGL$w-SB}KP+bk4|Jw1$l|FWqXq z`#B**H~#`{f`|LSv;p%uqzQ;4E``UsKzP$mQ1X-5P8U_iH$C1U#ffhNl&a5c>>%p; zmMTB1GrHQdzbo(PQX$3pb*7w_@k9ZERG;A#a149%QowBl{7uUNYLfm-O53dy%*4kh zIR1DOBhK_wxR7xDdkr=JydEFZh47I2D;8a|t*bR5o@{+`^@;iMo|WR6n3R{oyA2jS zJd+*c?+5I9eq$9|4MC`0jP!7F@@zYF%g}Un3T@+k_|fHpJl}B!W>QbpYYOfEMX=(c zUiD7U&7NcngKLh%iS?)jJ;YxwD{HS4RlDf7fej@wM>c554>zwD4D!+7N~fnpSlRsSRUgd zWJ~rir3`=-l}WOE=JM4d%HjcfN-Fupc4i(gCOY@eNMt%{8F}p#&pkd7V4QIi3y`y^3n{P#4S&{M5 zlw0p!4mif@&q+Nyy+sh6;F0@Nu}IF!b#)*(-htg?e^lS5MZS{TWtRu#V?Fe+Z=HFn z4!0%1Wu-g^t1Ync72*aePBE$$z*TC<#IsK_=g8k)($3nDE_@N z8|d{8HpYgKe$S9*p!IKKI-0J-=dIOb4QAW_m`s|zZ;yIIx|~l`Cy8J2;_nLx6}`Eg zYPMGCwR=6ic#4*Tb<_NjevoX1ZLH9A<^Ve!_ z6Z}0^KPz>JbuGK7a>S8jCseFY-X0KQ%jq+;uKyFl*cRw}z+X|tTbS>{^1)T2uk}p4 zCnC^`y+6Md)QzvimR$;1^b4>~wVe++h}?yO8TGNEUFQ*~`74!PHbR)sgZrlKFAU9F zla8}}lyG-PEIdl0+a^)9N8JkgFUplmch=-G^&gPr9t1qA^IDH;xxj@H4Gn`CUm~a#Dr}BSp5;rLPWh)^<6+ z;##mWj94GS7wlL+{4}yMb958r>sx9tMf2S+Hr$XfP=2HC{3$PGDB0x>txJE`6jxd^ zGU@3fQCoy`Ayi=#;|-JEvY4Q23t4#^$=0E)s!@lsmSFKdl~bE?%!Gii-^Q?EqW_0v z+iNZNI~#%5NdYZ3Wf0Emw^34GMbh1-s%+!7oU9$S527u5;tP6G@1Q)$6}=y#FfR?? zdk7;7f`l*$la={dkoWA;DTt@zZW4V9PiHv}D)k#10y(FussdJwppD?9u2n#mr4oz6M*Zgs| zLoh@@g_U;SQpvy?1Lfq@4JH?;wCES9BI{PYCcr@*c=@S6L6Hj2iy*<~8Ax)ASaSL!B!YVr2ooo@0T|JvE}9RvxtfRRauavK;^ z;9Gy^RMpuU%CO2DJ}BDf{30T^A|7a+$C6%?#VegKJ@m55lPqXXJ#fzSn3dEOV#tgg zoY6sSO!!f1{O!C690RUMosG9z#6?LriEw8E@s#~ftz3ckibjd_|M37FO~c1!5A7rV E2N4m&8UO$Q literal 0 HcmV?d00001 diff --git a/src/qt/sendcommunityfunddialog.cpp b/src/qt/sendcommunityfunddialog.cpp new file mode 100644 index 000000000..f8aed10b2 --- /dev/null +++ b/src/qt/sendcommunityfunddialog.cpp @@ -0,0 +1,150 @@ +#include "sendcommunityfunddialog.h" +#include "ui_sendcommunityfunddialog.h" + +#include +#include +#include +#include +#include +#include "consensus/cfund.h" +#include "main.h" +#include "base58.h" +#include "chain.h" + + +SendCommunityFundDialog::SendCommunityFundDialog(QWidget *parent, CFund::CProposal* proposal, int secDelay) : + QDialog(parent), + ui(new Ui::SendCommunityFundDialog), + proposal(proposal), + prequest(0), + secDelay(secDelay) +{ + ui->setupUi(this); + + connect(&countDownTimer, SIGNAL(timeout()), this, SLOT(countDown())); + connect(ui->pushButtonYes, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->pushButtonCancel, SIGNAL(clicked()), this, SLOT(reject())); + + ui->pushButtonCancel->setDefault(true); + updateYesButton(); + + // Set UI elements to proposal view + ui->labelProposalHashTitle->setVisible(false); + ui->labelProposalHash->setVisible(false); + ui->labelAddress->setText(QString(proposal->Address.c_str())); + + // Amount label + QSettings settings; + ui->labelRequestedAmount->setText(QString("%1 NAV / ").arg(proposal->nAmount/COIN).append("%1 EUR / ").arg(proposal->nAmount / settings.value("eurFactor", 0).toFloat()).append("%2 USD / ").arg(proposal->nAmount / settings.value("usdFactor", 0).toFloat()).append("%3 BTC").arg(proposal->nAmount / settings.value("btcFactor", 0).toFloat())); + + // Format long descriptions + std::string description = proposal->strDZeel.c_str(); + std::istringstream buf(description); + std::istream_iterator beg(buf), end; + std::string finalDescription = ""; + std::vector words(beg, end); + for(std::string word : words) { + unsigned int count = 0; + while(count < word.length()-1) { + if (count % 40 == 0 && count != 0) { + word.insert(count, "\n"); + } + count++; + } + finalDescription += word + " "; + } + + ui->labelDescription->setText(QString::fromStdString(finalDescription)); + ui->labelDuration->setText(GUIUtil::formatDurationStr(int(proposal->nDeadline))); + + string fee = std::to_string(Params().GetConsensus().nProposalMinimalFee / COIN); + string warning = "By submitting the proposal a " + fee + " NAV deduction will occur from your wallet "; + ui->labelWarning->setText(QString::fromStdString(warning)); +} + +SendCommunityFundDialog::SendCommunityFundDialog(QWidget *parent, CFund::CPaymentRequest* prequest, int secDelay) : + QDialog(parent), + ui(new Ui::SendCommunityFundDialog), + proposal(0), + prequest(prequest), + secDelay(secDelay) +{ + ui->setupUi(this); + + QDialog::setWindowTitle("Confirm Payment Request Details"); + + ui->pushButtonCancel->setDefault(true); + updateYesButton(); + + connect(&countDownTimer, SIGNAL(timeout()), this, SLOT(countDown())); + connect(ui->pushButtonYes, SIGNAL(clicked()), this, SLOT(accept())); + connect(ui->pushButtonCancel, SIGNAL(clicked()), this, SLOT(reject())); + + // Set UI elements to payment request view + ui->labelQuestionTitle->setText(QString("Are you sure you would like to create the following payment request?")); + ui->labelAddressTitle->setVisible(false); + ui->labelAddress->setVisible(false); + ui->labelDurationTitle->setVisible(false); + ui->labelDuration->setVisible(false); + ui->labelWarning->setVisible(false); + ui->labelProposalHash->setText(QString(prequest->proposalhash.ToString().c_str())); + ui->labelDescription->setText(QString(prequest->strDZeel.c_str())); + + // Amount label + QSettings settings; + ui->labelRequestedAmount->setText(QString("%1 NAV / ").arg(prequest->nAmount/COIN).append("%1 EUR / ").arg(prequest->nAmount / settings.value("eurFactor", 0).toFloat()).append("%2 USD / ").arg(prequest->nAmount / settings.value("usdFactor", 0).toFloat()).append("%3 BTC").arg(prequest->nAmount / settings.value("btcFactor", 0).toFloat())); + + // Format long descriptions + std::string description = prequest->strDZeel.c_str(); + std::istringstream buf(description); + std::istream_iterator beg(buf), end; + std::string finalDescription = ""; + std::vector words(beg, end); + for(std::string word : words) { + unsigned int count = 0; + while(count < word.length()-1) { + if (count % 40 == 0 && count != 0) { + word.insert(count, "\n"); + } + count++; + } + finalDescription += word + " "; + } + + ui->labelDescription->setText(QString::fromStdString(finalDescription)); +} + +void SendCommunityFundDialog::updateYesButton() +{ + if(secDelay > 0) + { + ui->pushButtonYes->setEnabled(false); + ui->pushButtonYes->setText(tr("Yes") + " (" + QString::number(secDelay) + ")"); + } + else + { + ui->pushButtonYes->setEnabled(true); + ui->pushButtonYes->setText(tr("Yes")); + } +} + +void SendCommunityFundDialog::countDown() +{ + secDelay--; + updateYesButton(); + + if(secDelay <= 0) + countDownTimer.stop(); +} + +int SendCommunityFundDialog::exec() +{ + updateYesButton(); + countDownTimer.start(1000); + return QDialog::exec(); +} + +SendCommunityFundDialog::~SendCommunityFundDialog() +{ + delete ui; +} diff --git a/src/qt/sendcommunityfunddialog.h b/src/qt/sendcommunityfunddialog.h new file mode 100644 index 000000000..95e864e0d --- /dev/null +++ b/src/qt/sendcommunityfunddialog.h @@ -0,0 +1,40 @@ +#ifndef SENDCOMMUNITYFUNDDIALOG_H +#define SENDCOMMUNITYFUNDDIALOG_H + +#include +#include +#include + +#include "../consensus/cfund.h" +#include "wallet/wallet.h" + +/* Confirmation dialog for proposals and payment requests. Widgets are hidden according if proposal or payment request*/ + +namespace Ui { +class SendCommunityFundDialog; +} + +class SendCommunityFundDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SendCommunityFundDialog(QWidget *parent = 0, CFund::CProposal* proposal = 0, int secDelay = 5); + explicit SendCommunityFundDialog(QWidget *parent = 0, CFund::CPaymentRequest* prequest = 0, int secDelay = 5); + int exec(); + ~SendCommunityFundDialog(); + +private Q_SLOTS: + void countDown(); + void updateYesButton(); + +private: + Ui::SendCommunityFundDialog *ui; + CFund::CProposal* proposal; + CFund::CPaymentRequest* prequest; + QTimer countDownTimer; + int secDelay; + CWallet *wallet; +}; + +#endif // SENDCOMMUNITYFUNDDIALOG_H diff --git a/src/qt/ui_getaddresstoreceive.h b/src/qt/ui_getaddresstoreceive.h index f9e6354aa..34ddbc84b 100644 --- a/src/qt/ui_getaddresstoreceive.h +++ b/src/qt/ui_getaddresstoreceive.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'getaddresstoreceive.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.9.5 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ @@ -219,16 +219,16 @@ class Ui_getAddressToReceive void retranslateUi(QWidget *getAddressToReceive) { - getAddressToReceive->setWindowTitle(QApplication::translate("getAddressToReceive", "Form", nullptr)); - label->setText(QApplication::translate("getAddressToReceive", "Use the following address to receive NavCoins:", nullptr)); + getAddressToReceive->setWindowTitle(QApplication::translate("getAddressToReceive", "Form", Q_NULLPTR)); + label->setText(QApplication::translate("getAddressToReceive", "Use the following address to receive NavCoins:", Q_NULLPTR)); #ifndef QT_NO_TOOLTIP - lblQRCode->setToolTip(QApplication::translate("getAddressToReceive", "QR Code", nullptr)); + lblQRCode->setToolTip(QApplication::translate("getAddressToReceive", "QR Code", Q_NULLPTR)); #endif // QT_NO_TOOLTIP - copyClipboardButton->setText(QApplication::translate("getAddressToReceive", "Copy to clipboard", nullptr)); - requestPaymentButton->setText(QApplication::translate("getAddressToReceive", "Request payment", nullptr)); - requestNewAddressButton->setText(QApplication::translate("getAddressToReceive", "List old addresses", nullptr)); - newAddressButton->setText(QApplication::translate("getAddressToReceive", "Generate a new address", nullptr)); - coldStakingButton->setText(QApplication::translate("getAddressToReceive", "Create a Cold Staking address", nullptr)); + copyClipboardButton->setText(QApplication::translate("getAddressToReceive", "Copy to clipboard", Q_NULLPTR)); + requestPaymentButton->setText(QApplication::translate("getAddressToReceive", "Request payment", Q_NULLPTR)); + requestNewAddressButton->setText(QApplication::translate("getAddressToReceive", "List old addresses", Q_NULLPTR)); + newAddressButton->setText(QApplication::translate("getAddressToReceive", "Generate a new address", Q_NULLPTR)); + coldStakingButton->setText(QApplication::translate("getAddressToReceive", "Create a Cold Staking address", Q_NULLPTR)); } // retranslateUi }; diff --git a/src/qt/ui_navtechsetup.h b/src/qt/ui_navtechsetup.h index bf9d29cb3..4bbc0b222 100644 --- a/src/qt/ui_navtechsetup.h +++ b/src/qt/ui_navtechsetup.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'navtechsetup.ui' ** -** Created by: Qt User Interface Compiler version 5.7.1 +** Created by: Qt User Interface Compiler version 5.9.5 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index effa9a828..96e494946 100755 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -221,6 +221,13 @@ void WalletFrame::gotoHistoryPage() i.value()->gotoHistoryPage(); } +void WalletFrame::gotoCommunityFundPage() +{ + QMap::const_iterator i; + for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) + i.value()->gotoCommunityFundPage(); +} + void WalletFrame::gotoReceiveCoinsPage() { QMap::const_iterator i; diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index a2887f684..874acc4e4 100755 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -45,7 +45,6 @@ class WalletFrame : public QFrame QWidget *topMenu; QHBoxLayout *menuLayout; - private: QStackedWidget *walletStack; NavCoinGUI *gui; @@ -63,6 +62,8 @@ public Q_SLOTS: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); + /** Switch to community fund page */ + void gotoCommunityFundPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 1ae8e44b0..7f08d3e88 100755 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -11,6 +11,7 @@ #include "guiutil.h" #include "optionsmodel.h" #include "overviewpage.h" +#include "communityfundpage.h" #include "platformstyle.h" #include "getaddresstoreceive.h" #include "receivecoinsdialog.h" @@ -54,6 +55,8 @@ WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): vbox->addLayout(hbox_buttons); transactionsPage->setLayout(vbox); + communityFundPage = new CommunityFundPage(platformStyle); + receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); sendCoinsPage = new SendCoinsDialog(platformStyle); requestPaymentPage = new getAddressToReceive(); @@ -66,6 +69,7 @@ WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): addWidget(receiveCoinsPage); addWidget(sendCoinsPage); addWidget(requestPaymentPage); + addWidget(communityFundPage); // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); @@ -126,6 +130,7 @@ void WalletView::setWalletModel(WalletModel *walletModel) // Put transaction list in tabs transactionView->setModel(walletModel); overviewPage->setWalletModel(walletModel); + communityFundPage->setWalletModel(walletModel); receiveCoinsPage->setModel(walletModel); requestPaymentPage->setModel(walletModel); requestPaymentPage->showQR(); @@ -185,6 +190,13 @@ void WalletView::gotoHistoryPage() setCurrentWidget(transactionsPage); } +void WalletView::gotoCommunityFundPage() +{ + // Change to CommunityFund UI + setCurrentWidget(communityFundPage); + communityFundPage->refreshTab(); +} + void WalletView::gotoReceiveCoinsPage() { setCurrentWidget(receiveCoinsPage); diff --git a/src/qt/walletview.h b/src/qt/walletview.h index f2e8f5f34..548668995 100755 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -13,6 +13,7 @@ class NavCoinGUI; class ClientModel; class OverviewPage; +class CommunityFundPage; class PlatformStyle; class ReceiveCoinsDialog; class SendCoinsDialog; @@ -64,6 +65,7 @@ class WalletView : public QStackedWidget QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + CommunityFundPage *communityFundPage; getAddressToReceive *requestPaymentPage; AddressBookPage *usedSendingAddressesPage; AddressBookPage *usedReceivingAddressesPage; @@ -78,6 +80,8 @@ public Q_SLOTS: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); + /** Switch to community fund page */ + void gotoCommunityFundPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ diff --git a/src/txdb.cpp b/src/txdb.cpp index 47581214a..1e7b9cf41 100755 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -214,6 +214,34 @@ bool CBlockTreeDB::GetProposalIndex(std::vector&vect) { return true; } +CFund::CProposal CBlockTreeDB::GetProposal(uint256 hash) +{ + boost::scoped_ptr pcursor(NewIterator()); + + pcursor->Seek(make_pair(DB_PROPINDEX, uint256())); + + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + std::pair key; + if (pcursor->GetKey(key) && key.first == DB_PROPINDEX) { + CFund::CProposal proposal; + if (pcursor->GetValue(proposal)) { + if(proposal.hash == hash){ + return proposal; + + } + pcursor->Next(); + } else { + return CFund::CProposal(); + } + } else { + break; + } + } + + return CFund::CProposal(); +} + bool CBlockTreeDB::ReadPaymentRequestIndex(const uint256 &prequestid, CFund::CPaymentRequest &prequest) { return Read(make_pair(DB_PREQINDEX, prequestid), prequest); } diff --git a/src/txdb.h b/src/txdb.h index d53c10626..fd72ec535 100755 --- a/src/txdb.h +++ b/src/txdb.h @@ -165,6 +165,7 @@ class CBlockTreeDB : public CDBWrapper bool ReadProposalIndex(const uint256 &proposalid, CFund::CProposal &proposal); bool WriteProposalIndex(const std::vector >&vect); bool GetProposalIndex(std::vector&vect); + CFund::CProposal GetProposal(uint256 hash); bool UpdateProposalIndex(const std::vector >&vect); bool ReadPaymentRequestIndex(const uint256 &prequestid, CFund::CPaymentRequest &prequest); bool WritePaymentRequestIndex(const std::vector >&vect); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f10418c76..5aed76795 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4134,6 +4134,19 @@ bool CWallet::BackupWallet(const std::string& strDest) return false; } +std::string CWallet::formatDisplayAmount(CAmount amount) { + stringstream n; + n.imbue(std::locale("")); + n << fixed << setprecision(8) << amount/COIN; + string nav_amount = n.str(); + if(nav_amount.at(nav_amount.length()-1) == '.') { + nav_amount = nav_amount.substr(0, nav_amount.size()-1); + } + nav_amount.append(" NAV"); + + return nav_amount; +} + CKeyPool::CKeyPool() { nTime = GetTime(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index becc45370..095c0065b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -995,6 +995,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool BackupWallet(const std::string& strDest); + std::string formatDisplayAmount(CAmount amount); + /* Set the HD chain model (chain child index counters) */ bool SetHDChain(const CHDChain& chain, bool memonly); const CHDChain& GetHDChain() { return hdChain; }