| 111 | } |
| 112 | |
| 113 | WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet) |
| 114 | { |
| 115 | QMutexLocker locker(&m_mutex); |
| 116 | |
| 117 | // Return model instance if exists. |
| 118 | if (!m_wallets.empty()) { |
| 119 | std::string name = wallet->getWalletName(); |
| 120 | for (WalletModel* wallet_model : m_wallets) { |
| 121 | if (wallet_model->wallet().getWalletName() == name) { |
| 122 | return wallet_model; |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | // Instantiate model and register it. |
| 128 | WalletModel* wallet_model = new WalletModel(std::move(wallet), m_client_model, m_platform_style, |
| 129 | nullptr /* required for the following moveToThread() call */); |
| 130 | |
| 131 | // Move WalletModel object to the thread that created the WalletController |
| 132 | // object (GUI main thread), instead of the current thread, which could be |
| 133 | // an outside wallet thread or RPC thread sending a LoadWallet notification. |
| 134 | // This ensures queued signals sent to the WalletModel object will be |
| 135 | // handled on the GUI event loop. |
| 136 | wallet_model->moveToThread(thread()); |
| 137 | // setParent(parent) must be called in the thread which created the parent object. More details in #18948. |
| 138 | GUIUtil::ObjectInvoke(this, [wallet_model, this] { |
| 139 | wallet_model->setParent(this); |
| 140 | }, GUIUtil::blockingGUIThreadConnection()); |
| 141 | |
| 142 | m_wallets.push_back(wallet_model); |
| 143 | |
| 144 | // WalletModel::startPollBalance needs to be called in a thread managed by |
| 145 | // Qt because of startTimer. Considering the current thread can be a RPC |
| 146 | // thread, better delegate the calling to Qt with Qt::AutoConnection. |
| 147 | const bool called = QMetaObject::invokeMethod(wallet_model, "startPollBalance"); |
| 148 | assert(called); |
| 149 | |
| 150 | connect(wallet_model, &WalletModel::unload, this, [this, wallet_model] { |
| 151 | // Defer removeAndDeleteWallet when no modal widget is active. |
| 152 | // TODO: remove this workaround by removing usage of QDialog::exec. |
| 153 | if (QApplication::activeModalWidget()) { |
| 154 | connect(qApp, &QApplication::focusWindowChanged, wallet_model, [this, wallet_model]() { |
| 155 | if (!QApplication::activeModalWidget()) { |
| 156 | removeAndDeleteWallet(wallet_model); |
| 157 | } |
| 158 | }, Qt::QueuedConnection); |
| 159 | } else { |
| 160 | removeAndDeleteWallet(wallet_model); |
| 161 | } |
| 162 | }, Qt::QueuedConnection); |
| 163 | |
| 164 | // Re-emit coinsSent signal from wallet model. |
| 165 | //TODO(stevenroose) fix |
| 166 | //connect(wallet_model, &WalletModel::coinsSent, this, &WalletController::coinsSent); |
| 167 | |
| 168 | Q_EMIT walletAdded(wallet_model); |
| 169 | |
| 170 | return wallet_model; |
no test coverage detected