VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/cloud/UICloudProfileDetailsWidget.cpp@ 82781

Last change on this file since 82781 was 76606, checked in by vboxsync, 5 years ago

FE/Qt: Cleaning out old precompiled header experiment.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
1/* $Id: UICloudProfileDetailsWidget.cpp 76606 2019-01-02 05:40:39Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UICloudProfileDetailsWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QGridLayout>
20#include <QHeaderView>
21#include <QLabel>
22#include <QLineEdit>
23#include <QPushButton>
24#include <QTableWidget>
25#include <QVBoxLayout>
26
27/* GUI includes: */
28#include "QIDialogButtonBox.h"
29#include "UICloudProfileDetailsWidget.h"
30
31/* Other VBox includes: */
32#include "iprt/assert.h"
33
34
35UICloudProfileDetailsWidget::UICloudProfileDetailsWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */)
36 : QIWithRetranslateUI<QWidget>(pParent)
37 , m_enmEmbedding(enmEmbedding)
38 , m_pTableWidget(0)
39 , m_pButtonBox(0)
40{
41 /* Prepare: */
42 prepare();
43}
44
45void UICloudProfileDetailsWidget::setData(const UIDataCloudProfile &data)
46{
47 /* Cache old/new data: */
48 m_oldData = data;
49 m_newData = m_oldData;
50
51 /* Load data: */
52 loadData();
53
54 /* Translate linked widgets: */
55 retranslateEditor();
56 retranslateButtons();
57}
58
59void UICloudProfileDetailsWidget::retranslateUi()
60{
61 /// @todo add description tool-tips
62
63 /* Translate name-editor label: */
64 m_pLabelName->setText(tr("Name:"));
65 /* Translate name-editor: */
66 retranslateEditor();
67
68 /* Translate table-widget label: */
69 m_pLabelTableWidget->setText(tr("Properties:"));
70 /* Translate table-widget: */
71 m_pTableWidget->setToolTip(tr("Contains cloud profile settings"));
72
73 /* Translate buttons: */
74 retranslateButtons();
75
76 /* Retranslate validation: */
77 retranslateValidation();
78
79 /* Update table tool-tips: */
80 updateTableToolTips();
81}
82
83void UICloudProfileDetailsWidget::retranslateEditor()
84{
85 /* Translate placeholders: */
86 m_pEditorName->setPlaceholderText( m_oldData.m_strName.isNull()
87 ? tr("Enter a name for the new profile...")
88 : tr("Enter a name for this profile..."));
89}
90
91void UICloudProfileDetailsWidget::retranslateButtons()
92{
93 /* Translate button-box: */
94 if (m_pButtonBox)
95 {
96 /* Common: 'Reset' button: */
97 m_pButtonBox->button(QDialogButtonBox::Cancel)->setText(tr("Reset"));
98 m_pButtonBox->button(QDialogButtonBox::Cancel)->setStatusTip(tr("Reset changes in current profile details"));
99 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape);
100 m_pButtonBox->button(QDialogButtonBox::Cancel)->
101 setToolTip(tr("Reset Changes (%1)").arg(m_pButtonBox->button(QDialogButtonBox::Cancel)->shortcut().toString()));
102
103 if (m_oldData.m_strName.isNull())
104 {
105 /* Provider: 'Add' button: */
106 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Add"));
107 m_pButtonBox->button(QDialogButtonBox::Ok)->setStatusTip(tr("Add a new profile with following name"));
108 m_pButtonBox->button(QDialogButtonBox::Ok)->setShortcut(QString("Ctrl+Return"));
109 m_pButtonBox->button(QDialogButtonBox::Ok)->
110 setToolTip(tr("Add Profile (%1)").arg(m_pButtonBox->button(QDialogButtonBox::Ok)->shortcut().toString()));
111 }
112 else
113 {
114 /* Profile: 'Apply' button: */
115 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Apply"));
116 m_pButtonBox->button(QDialogButtonBox::Ok)->setStatusTip(tr("Apply changes in current profile details"));
117 m_pButtonBox->button(QDialogButtonBox::Ok)->setShortcut(QString("Ctrl+Return"));
118 m_pButtonBox->button(QDialogButtonBox::Ok)->
119 setToolTip(tr("Apply Changes (%1)").arg(m_pButtonBox->button(QDialogButtonBox::Ok)->shortcut().toString()));
120 }
121 }
122}
123
124void UICloudProfileDetailsWidget::sltNameChanged(const QString &strName)
125{
126 /* Push changes back: */
127 m_newData.m_strName = strName;
128
129 /* Revalidate: */
130 revalidate(m_pEditorName);
131 /* Update button states: */
132 updateButtonStates();
133}
134
135void UICloudProfileDetailsWidget::sltTableChanged(QTableWidgetItem *pItem)
136{
137 /* Make sure item is valid: */
138 AssertPtrReturnVoid(pItem);
139 const int iRow = pItem->row();
140 AssertReturnVoid(iRow >= 0);
141
142 /* Skip if one of items isn't yet created.
143 * This can happen when 1st is already while 2nd isn't yet. */
144 QTableWidgetItem *pItemK = m_pTableWidget->item(iRow, 0);
145 QTableWidgetItem *pItemV = m_pTableWidget->item(iRow, 1);
146 if (!pItemK || !pItemV)
147 return;
148
149 /* Push changes back: */
150 const QString strKey = pItemK->text();
151 const QString strValue = pItemV->text();
152 m_newData.m_data[strKey] = qMakePair(strValue, m_newData.m_data.value(strKey).second);
153
154 /* Revalidate: */
155 revalidate(m_pTableWidget);
156 /* Update button states: */
157 updateButtonStates();
158}
159
160void UICloudProfileDetailsWidget::sltHandleButtonBoxClick(QAbstractButton *pButton)
161{
162 /* Make sure button-box exists: */
163 AssertPtrReturnVoid(m_pButtonBox);
164
165 /* Disable buttons first of all: */
166 m_pButtonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
167 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
168
169 /* Compare with known buttons: */
170 if (pButton == m_pButtonBox->button(QDialogButtonBox::Cancel))
171 emit sigDataChangeRejected();
172 else
173 if (pButton == m_pButtonBox->button(QDialogButtonBox::Ok))
174 emit sigDataChangeAccepted();
175}
176
177void UICloudProfileDetailsWidget::prepare()
178{
179 /* Prepare widgets: */
180 prepareWidgets();
181
182 /* Apply language settings: */
183 retranslateUi();
184
185 /* Update button states finally: */
186 updateButtonStates();
187}
188
189void UICloudProfileDetailsWidget::prepareWidgets()
190{
191 /* Create layout: */
192 QGridLayout *pLayout = new QGridLayout(this);
193 if (pLayout)
194 {
195 if (m_enmEmbedding == EmbedTo_Dialog)
196 {
197 pLayout->setContentsMargins(0, 0, 0, 0);
198#ifdef VBOX_WS_MAC
199 pLayout->setSpacing(10);
200#else
201 pLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2);
202#endif
203 }
204 else
205 {
206#ifdef VBOX_WS_MAC
207 pLayout->setContentsMargins(13, 0, 13, 13);
208 pLayout->setSpacing(10);
209#else
210 const int iL = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) * 1.5;
211 const int iT = qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin) * 1.5;
212 const int iR = qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin) * 1.5;
213 const int iB = qApp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin) * 1.5;
214 pLayout->setContentsMargins(iL, iT, iR, iB);
215#endif
216 }
217
218 /* Create name editor: */
219 m_pEditorName = new QLineEdit;
220 if (m_pEditorName)
221 {
222 connect(m_pEditorName, &QLineEdit::textChanged, this, &UICloudProfileDetailsWidget::sltNameChanged);
223
224 /* Add into layout: */
225 pLayout->addWidget(m_pEditorName, 0, 1);
226 }
227 /* Create name label: */
228 m_pLabelName = new QLabel;
229 if (m_pLabelName)
230 {
231 m_pLabelName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
232 m_pLabelName->setBuddy(m_pEditorName);
233
234 /* Add into layout: */
235 pLayout->addWidget(m_pLabelName, 0, 0);
236 }
237
238 /* Create tab-widget: */
239 m_pTableWidget = new QTableWidget;
240 if (m_pTableWidget)
241 {
242 m_pTableWidget->setAlternatingRowColors(true);
243 m_pTableWidget->horizontalHeader()->setVisible(false);
244 m_pTableWidget->verticalHeader()->setVisible(false);
245 m_pTableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
246 connect(m_pTableWidget, &QTableWidget::itemChanged, this, &UICloudProfileDetailsWidget::sltTableChanged);
247
248 /* Add into layout: */
249 pLayout->addWidget(m_pTableWidget, 1, 1);
250 }
251 /* Create tab-widget label: */
252 m_pLabelTableWidget = new QLabel;
253 if (m_pLabelTableWidget)
254 {
255 m_pLabelTableWidget->setAlignment(Qt::AlignRight | Qt::AlignTop);
256 m_pLabelTableWidget->setBuddy(m_pTableWidget);
257
258 /* Add into layout: */
259 pLayout->addWidget(m_pLabelTableWidget, 1, 0);
260 }
261
262 /* If parent embedded into stack: */
263 if (m_enmEmbedding == EmbedTo_Stack)
264 {
265 /* Create button-box: */
266 m_pButtonBox = new QIDialogButtonBox;
267 if (m_pButtonBox)
268 {
269 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
270 connect(m_pButtonBox, &QIDialogButtonBox::clicked, this, &UICloudProfileDetailsWidget::sltHandleButtonBoxClick);
271
272 /* Add into layout: */
273 pLayout->addWidget(m_pButtonBox, 2, 0, 1, 2);
274 }
275 }
276 }
277}
278
279void UICloudProfileDetailsWidget::loadData()
280{
281 /* Clear table initially: */
282 m_pTableWidget->clear();
283
284 /* Fill name editor: */
285 m_pEditorName->setText(m_oldData.m_strName);
286
287 /* Configure table: */
288 m_pTableWidget->setRowCount(m_oldData.m_data.keys().size());
289 m_pTableWidget->setColumnCount(2);
290
291 /* Push acquired keys/values to data fields: */
292 for (int i = 0; i < m_pTableWidget->rowCount(); ++i)
293 {
294 /* Gather values: */
295 const QString strKey = m_oldData.m_data.keys().at(i);
296 const QString strValue = m_oldData.m_data.value(strKey).first;
297 const QString strToolTip = m_oldData.m_data.value(strKey).second;
298
299 /* Create key item: */
300 QTableWidgetItem *pItemK = new QTableWidgetItem(strKey);
301 if (pItemK)
302 {
303 /* Non-editable for sure, but non-selectable? */
304 pItemK->setFlags(pItemK->flags() & ~Qt::ItemIsEditable);
305 /* Use non-translated description as tool-tip: */
306 pItemK->setData(Qt::UserRole, strToolTip);
307
308 /* Insert into table: */
309 m_pTableWidget->setItem(i, 0, pItemK);
310 }
311
312 /* Create value item: */
313 QTableWidgetItem *pItemV = new QTableWidgetItem(strValue);
314 if (pItemV)
315 {
316 /* Use the value as tool-tip, there can be quite long values: */
317 pItemV->setToolTip(strValue);
318
319 /* Insert into table: */
320 m_pTableWidget->setItem(i, 1, pItemV);
321 }
322 }
323
324 /* Update table tooltips: */
325 updateTableToolTips();
326 /* Adjust table contents: */
327 adjustTableContents();
328}
329
330void UICloudProfileDetailsWidget::revalidate(QWidget *pWidget /* = 0 */)
331{
332 /// @todo validate profile settings table!
333
334 /* Retranslate validation: */
335 retranslateValidation(pWidget);
336}
337
338void UICloudProfileDetailsWidget::retranslateValidation(QWidget *pWidget /* = 0 */)
339{
340 Q_UNUSED(pWidget);
341
342 /// @todo translate vaidation errors!
343}
344
345void UICloudProfileDetailsWidget::updateTableToolTips()
346{
347 /* Iterate through all the key items: */
348 for (int i = 0; i < m_pTableWidget->rowCount(); ++i)
349 {
350 /* Acquire current key item: */
351 QTableWidgetItem *pItemK = m_pTableWidget->item(i, 0);
352 if (pItemK)
353 {
354 const QString strToolTip = pItemK->data(Qt::UserRole).toString();
355 pItemK->setToolTip(tr(strToolTip.toUtf8().constData()));
356 }
357 }
358}
359
360void UICloudProfileDetailsWidget::adjustTableContents()
361{
362 /* Disable last column stretching temporary: */
363 m_pTableWidget->horizontalHeader()->setStretchLastSection(false);
364
365 /* Resize both columns to contents: */
366 m_pTableWidget->resizeColumnsToContents();
367 /* Then acquire full available width: */
368 const int iFullWidth = m_pTableWidget->viewport()->width();
369 /* First column should not be less than it's minimum size, last gets the rest: */
370 const int iMinimumWidth0 = qMin(m_pTableWidget->horizontalHeader()->sectionSize(0), iFullWidth / 2);
371 m_pTableWidget->horizontalHeader()->resizeSection(0, iMinimumWidth0);
372
373 /* Enable last column stretching again: */
374 m_pTableWidget->horizontalHeader()->setStretchLastSection(true);
375}
376
377void UICloudProfileDetailsWidget::updateButtonStates()
378{
379#if 0
380 if (m_oldData != m_newData)
381 {
382 printf("Old data:\n");
383 foreach (const QString &strKey, m_oldData.m_data.keys())
384 {
385 const QString strValue = m_oldData.m_data.value(strKey).first;
386 const QString strDecription = m_oldData.m_data.value(strKey).second;
387 printf(" %s: %s, %s\n", strKey.toUtf8().constData(), strValue.toUtf8().constData(), strDecription.toUtf8().constData());
388 }
389 printf("New data:\n");
390 foreach (const QString &strKey, m_newData.m_data.keys())
391 {
392 const QString strValue = m_newData.m_data.value(strKey).first;
393 const QString strDecription = m_newData.m_data.value(strKey).second;
394 printf(" %s: %s, %s\n", strKey.toUtf8().constData(), strValue.toUtf8().constData(), strDecription.toUtf8().constData());
395 }
396 printf("\n");
397 }
398#endif
399
400 /* Update 'Apply' / 'Reset' button states: */
401 if (m_pButtonBox)
402 {
403 m_pButtonBox->button(QDialogButtonBox::Cancel)->setEnabled(m_oldData != m_newData);
404 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(m_oldData != m_newData);
405 }
406
407 /* Notify listeners as well: */
408 emit sigDataChanged(m_oldData != m_newData);
409}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use