Changeset 43528 in vbox for trunk/src/VBox
- Timestamp:
- Oct 3, 2012 2:09:25 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 81116
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserModel.cpp
r43514 r43528 133 133 } 134 134 135 UIGChooserItem* UIGChooserModel::mainRoot() const136 {137 return m_rootStack.first();138 }139 140 UIGChooserItem* UIGChooserModel::root() const141 {142 return m_rootStack.last();143 }144 145 void UIGChooserModel::indentRoot(UIGChooserItem *pNewRootItem)146 {147 /* Do nothing is sliding already: */148 if (m_fSliding)149 return;150 151 /* We are sliding: */152 m_fSliding = true;153 emit sigSlidingStarted();154 155 /* Hiding root: */156 root()->hide();157 158 /* Create left root: */159 bool fLeftRootIsMain = root() == mainRoot();160 m_pLeftRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), fLeftRootIsMain);161 m_pLeftRoot->setPos(0, 0);162 m_pLeftRoot->resize(root()->geometry().size());163 164 /* Create right root: */165 m_pRightRoot = new UIGChooserItemGroup(scene(), pNewRootItem->toGroupItem(), false);166 m_pRightRoot->setPos(root()->geometry().width(), 0);167 m_pRightRoot->resize(root()->geometry().size());168 169 /* Indent root: */170 m_rootStack << pNewRootItem;171 root()->setRoot(true);172 m_pAfterSlidingFocus = root()->items().first();173 174 /* Slide root: */175 slideRoot(true);176 }177 178 void UIGChooserModel::unindentRoot()179 {180 /* Do nothing is sliding already: */181 if (m_fSliding)182 return;183 184 /* We are sliding: */185 m_fSliding = true;186 emit sigSlidingStarted();187 188 /* Hiding root: */189 root()->hide();190 root()->setRoot(false);191 192 /* Create left root: */193 bool fLeftRootIsMain = m_rootStack.at(m_rootStack.size() - 2) == mainRoot();194 m_pLeftRoot = new UIGChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem(), fLeftRootIsMain);195 m_pLeftRoot->setPos(- root()->geometry().width(), 0);196 m_pLeftRoot->resize(root()->geometry().size());197 198 /* Create right root: */199 m_pRightRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), false);200 m_pRightRoot->setPos(0, 0);201 m_pRightRoot->resize(root()->geometry().size());202 203 /* Unindent root: */204 m_pAfterSlidingFocus = root();205 m_rootStack.removeLast();206 207 /* Slide root: */208 slideRoot(false);209 }210 211 bool UIGChooserModel::isSlidingInProgress() const212 {213 return m_fSliding;214 }215 216 void UIGChooserModel::setCurrentItem(int iItemIndex)217 {218 /* Make sure passed index feats the bounds: */219 if (iItemIndex >= 0 && iItemIndex < navigationList().size())220 {221 /* And call for other wrapper: */222 setCurrentItem(navigationList().at(iItemIndex));223 }224 else225 AssertMsgFailed(("Passed index out of bounds!"));226 }227 228 void UIGChooserModel::setCurrentItem(UIGChooserItem *pItem)229 {230 /* If navigation list contains passed item: */231 if (navigationList().contains(pItem))232 {233 /* Pass focus/selection to that item: */234 setFocusItem(pItem, true);235 }236 else237 AssertMsgFailed(("Passed item not in navigation list!"));238 }239 240 void UIGChooserModel::unsetCurrentItem()241 {242 /* Clear focus/selection: */243 setFocusItem(0, true);244 }245 246 UIVMItem* UIGChooserModel::currentItem() const247 {248 /* Search for the first selected machine: */249 return searchCurrentItem(selectionList());250 }251 252 QList<UIVMItem*> UIGChooserModel::currentItems() const253 {254 /* Populate list of selected machines: */255 QList<UIVMItem*> currentItemList;256 enumerateCurrentItems(selectionList(), currentItemList);257 return currentItemList;258 }259 260 void UIGChooserModel::setCurrentItemDefinition(const QString &strDefinition)261 {262 /* Make sure something was passed: */263 if (strDefinition.isEmpty())264 {265 if (mainRoot()->hasItems())266 setCurrentItem(0);267 else268 unsetCurrentItem();269 return;270 }271 272 /* Parse definitions: */273 QString strItemType = strDefinition.section('=', 0, 0);274 QString strItemName = strDefinition.section('=', 1, -1);275 UIGChooserItem *pItem = 0;276 277 /* Its group item? */278 if (strItemType == "g")279 {280 /* Make sure group item with passed id exists: */281 pItem = findGroupItem(strItemName, mainRoot());282 }283 /* Its machine item? */284 else if (strItemType == "m")285 {286 /* Make sure machine with passed name registered: */287 CMachine machine = vboxGlobal().virtualBox().FindMachine(strItemName);288 if (!machine.isNull())289 {290 /* Make sure machine item with passed id exists: */291 pItem = findMachineItem(machine.GetName(), mainRoot());292 }293 }294 295 /* Found nothing? */296 if (!pItem)297 {298 setCurrentItem(0);299 return;300 }301 302 /* Select desired item: */303 if (navigationList().contains(pItem))304 setCurrentItem(pItem);305 else306 setCurrentItem(0);307 }308 309 QString UIGChooserModel::currentItemDefinition() const310 {311 /* Determine item type: */312 QString strItemType;313 QString strItemName;314 315 /* Get first selected item: */316 UIGChooserItem *pSelectedItem = selectionList().isEmpty() ? 0 : selectionList().first();317 /* Item exists? */318 if (pSelectedItem)319 {320 /* Update item type: */321 if (pSelectedItem->type() == UIGChooserItemType_Group)322 strItemType = "g";323 else if (pSelectedItem->type() == UIGChooserItemType_Machine)324 strItemType = "m";325 326 /* Update item name: */327 strItemName = pSelectedItem->name();328 }329 330 /* Return result: */331 return pSelectedItem ? strItemType + "=" + strItemName : QString();332 }333 334 bool UIGChooserModel::isSingleGroupSelected() const335 {336 return selectionList().size() == 1 &&337 selectionList().first()->type() == UIGChooserItemType_Group;338 }339 340 bool UIGChooserModel::isAllItemsOfOneGroupSelected() const341 {342 /* Make sure at least on item selected: */343 if (selectionList().isEmpty())344 return false;345 346 /* Determine the parent group of the first item: */347 UIGChooserItem *pFirstParent = selectionList().first()->parentItem();348 349 /* Make sure this parent is not main root item: */350 if (pFirstParent == mainRoot())351 return false;352 353 /* Enumerate selected set: */354 QSet<UIGChooserItem*> selectedSet;355 foreach (UIGChooserItem *pSelectedItem, selectionList())356 selectedSet << pSelectedItem;357 358 /* Enumerate first parent children set: */359 QSet<UIGChooserItem*> firstParentSet;360 foreach (UIGChooserItem *pSelectedItem, pFirstParent->items())361 firstParentSet << pSelectedItem;362 363 /* Check if both sets contains the same: */364 return selectedSet == firstParentSet;365 }366 367 void UIGChooserModel::setFocusItem(UIGChooserItem *pItem, bool fWithSelection /* = false */)368 {369 /* Make sure real focus unset: */370 clearRealFocus();371 372 /* Something changed? */373 if (m_pFocusItem != pItem || !pItem)374 {375 /* Remember previous focus item: */376 QPointer<UIGChooserItem> pPreviousFocusItem = m_pFocusItem;377 /* Set new focus item: */378 m_pFocusItem = pItem;379 380 /* Should we move selection too? */381 if (fWithSelection)382 {383 /* Clear selection: */384 clearSelectionList();385 /* Add focus item into selection (if any): */386 if (m_pFocusItem)387 addToSelectionList(m_pFocusItem);388 /* Notify selection changed: */389 notifySelectionChanged();390 }391 392 /* Update previous focus item (if any): */393 if (pPreviousFocusItem)394 {395 disconnect(pPreviousFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed()));396 pPreviousFocusItem->update();397 }398 /* Update new focus item (if any): */399 if (m_pFocusItem)400 {401 connect(m_pFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed()));402 m_pFocusItem->update();403 }404 405 /* Notify focus changed: */406 emit sigFocusChanged(m_pFocusItem);407 }408 }409 410 UIGChooserItem* UIGChooserModel::focusItem() const411 {412 return m_pFocusItem;413 }414 415 135 QGraphicsItem* UIGChooserModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const 416 136 { 417 137 return scene()->itemAt(position, deviceTransform); 418 }419 420 void UIGChooserModel::updateGroupTree()421 {422 updateGroupTree(mainRoot());423 }424 425 const QList<UIGChooserItem*>& UIGChooserModel::navigationList() const426 {427 return m_navigationList;428 }429 430 void UIGChooserModel::removeFromNavigationList(UIGChooserItem *pItem)431 {432 AssertMsg(pItem, ("Passed item is invalid!"));433 m_navigationList.removeAll(pItem);434 }435 436 void UIGChooserModel::clearNavigationList()437 {438 m_navigationList.clear();439 }440 441 void UIGChooserModel::updateNavigation()442 {443 /* Recreate navigation list: */444 clearNavigationList();445 m_navigationList = createNavigationList(root());446 }447 448 const QList<UIGChooserItem*>& UIGChooserModel::selectionList() const449 {450 return m_selectionList;451 }452 453 void UIGChooserModel::addToSelectionList(UIGChooserItem *pItem)454 {455 AssertMsg(pItem, ("Passed item is invalid!"));456 m_selectionList << pItem;457 pItem->update();458 }459 460 void UIGChooserModel::removeFromSelectionList(UIGChooserItem *pItem)461 {462 AssertMsg(pItem, ("Passed item is invalid!"));463 m_selectionList.removeAll(pItem);464 pItem->update();465 }466 467 void UIGChooserModel::clearSelectionList()468 {469 QList<UIGChooserItem*> oldSelectedList = m_selectionList;470 m_selectionList.clear();471 foreach (UIGChooserItem *pItem, oldSelectedList)472 pItem->update();473 }474 475 void UIGChooserModel::notifySelectionChanged()476 {477 /* Make sure selection item list is never empty478 * if at least one item (for example 'focus') present: */479 if (selectionList().isEmpty() && focusItem())480 addToSelectionList(focusItem());481 /* Notify listeners about selection change: */482 emit sigSelectionChanged();483 138 } 484 139 … … 508 163 } 509 164 510 void UIGChooserModel::startEditing() 511 { 512 sltStartEditingSelectedGroup(); 513 } 514 515 void UIGChooserModel::setCurrentDragObject(QDrag *pDragObject) 165 const QList<UIGChooserItem*>& UIGChooserModel::navigationList() const 166 { 167 return m_navigationList; 168 } 169 170 void UIGChooserModel::removeFromNavigationList(UIGChooserItem *pItem) 171 { 172 AssertMsg(pItem, ("Passed item is invalid!")); 173 m_navigationList.removeAll(pItem); 174 } 175 176 void UIGChooserModel::clearNavigationList() 177 { 178 m_navigationList.clear(); 179 } 180 181 void UIGChooserModel::updateNavigation() 182 { 183 /* Recreate navigation list: */ 184 clearNavigationList(); 185 m_navigationList = createNavigationList(root()); 186 } 187 188 UIVMItem* UIGChooserModel::currentItem() const 189 { 190 /* Search for the first selected machine: */ 191 return searchCurrentItem(selectionList()); 192 } 193 194 QString UIGChooserModel::currentItemDefinition() const 195 { 196 /* Determine item type: */ 197 QString strItemType; 198 QString strItemName; 199 200 /* Get first selected item: */ 201 UIGChooserItem *pSelectedItem = selectionList().isEmpty() ? 0 : selectionList().first(); 202 /* Item exists? */ 203 if (pSelectedItem) 204 { 205 /* Update item type: */ 206 if (pSelectedItem->type() == UIGChooserItemType_Group) 207 strItemType = "g"; 208 else if (pSelectedItem->type() == UIGChooserItemType_Machine) 209 strItemType = "m"; 210 211 /* Update item name: */ 212 strItemName = pSelectedItem->name(); 213 } 214 215 /* Return result: */ 216 return pSelectedItem ? strItemType + "=" + strItemName : QString(); 217 } 218 219 QList<UIVMItem*> UIGChooserModel::currentItems() const 220 { 221 /* Populate list of selected machines: */ 222 QList<UIVMItem*> currentItemList; 223 enumerateCurrentItems(selectionList(), currentItemList); 224 return currentItemList; 225 } 226 227 const QList<UIGChooserItem*>& UIGChooserModel::selectionList() const 228 { 229 return m_selectionList; 230 } 231 232 void UIGChooserModel::setCurrentItem(int iItemIndex) 233 { 234 /* Make sure passed index feats the bounds: */ 235 if (iItemIndex >= 0 && iItemIndex < navigationList().size()) 236 { 237 /* And call for other wrapper: */ 238 setCurrentItem(navigationList().at(iItemIndex)); 239 } 240 else 241 AssertMsgFailed(("Passed index out of bounds!")); 242 } 243 244 void UIGChooserModel::setCurrentItem(UIGChooserItem *pItem) 245 { 246 /* If navigation list contains passed item: */ 247 if (navigationList().contains(pItem)) 248 { 249 /* Pass focus/selection to that item: */ 250 setFocusItem(pItem, true); 251 } 252 else 253 AssertMsgFailed(("Passed item not in navigation list!")); 254 } 255 256 void UIGChooserModel::setCurrentItemDefinition(const QString &strDefinition) 257 { 258 /* Make sure something was passed: */ 259 if (strDefinition.isEmpty()) 260 { 261 if (mainRoot()->hasItems()) 262 setCurrentItem(0); 263 else 264 unsetCurrentItem(); 265 return; 266 } 267 268 /* Parse definitions: */ 269 QString strItemType = strDefinition.section('=', 0, 0); 270 QString strItemName = strDefinition.section('=', 1, -1); 271 UIGChooserItem *pItem = 0; 272 273 /* Its group item? */ 274 if (strItemType == "g") 275 { 276 /* Make sure group item with passed id exists: */ 277 pItem = findGroupItem(strItemName, mainRoot()); 278 } 279 /* Its machine item? */ 280 else if (strItemType == "m") 281 { 282 /* Make sure machine with passed name registered: */ 283 CMachine machine = vboxGlobal().virtualBox().FindMachine(strItemName); 284 if (!machine.isNull()) 285 { 286 /* Make sure machine item with passed id exists: */ 287 pItem = findMachineItem(machine.GetName(), mainRoot()); 288 } 289 } 290 291 /* Found nothing? */ 292 if (!pItem) 293 { 294 setCurrentItem(0); 295 return; 296 } 297 298 /* Select desired item: */ 299 if (navigationList().contains(pItem)) 300 setCurrentItem(pItem); 301 else 302 setCurrentItem(0); 303 } 304 305 void UIGChooserModel::unsetCurrentItem() 306 { 307 /* Clear focus/selection: */ 308 setFocusItem(0, true); 309 } 310 311 void UIGChooserModel::addToSelectionList(UIGChooserItem *pItem) 312 { 313 AssertMsg(pItem, ("Passed item is invalid!")); 314 m_selectionList << pItem; 315 pItem->update(); 316 } 317 318 void UIGChooserModel::removeFromSelectionList(UIGChooserItem *pItem) 319 { 320 AssertMsg(pItem, ("Passed item is invalid!")); 321 m_selectionList.removeAll(pItem); 322 pItem->update(); 323 } 324 325 void UIGChooserModel::clearSelectionList() 326 { 327 QList<UIGChooserItem*> oldSelectedList = m_selectionList; 328 m_selectionList.clear(); 329 foreach (UIGChooserItem *pItem, oldSelectedList) 330 pItem->update(); 331 } 332 333 void UIGChooserModel::notifySelectionChanged() 334 { 335 /* Make sure selection item list is never empty 336 * if at least one item (for example 'focus') present: */ 337 if (selectionList().isEmpty() && focusItem()) 338 addToSelectionList(focusItem()); 339 /* Notify listeners about selection change: */ 340 emit sigSelectionChanged(); 341 } 342 343 void UIGChooserModel::activate() 344 { 345 gActionPool->action(UIActionIndexSelector_State_Common_StartOrShow)->activate(QAction::Trigger); 346 } 347 348 bool UIGChooserModel::isSingleGroupSelected() const 349 { 350 return selectionList().size() == 1 && 351 selectionList().first()->type() == UIGChooserItemType_Group; 352 } 353 354 bool UIGChooserModel::isAllItemsOfOneGroupSelected() const 355 { 356 /* Make sure at least on item selected: */ 357 if (selectionList().isEmpty()) 358 return false; 359 360 /* Determine the parent group of the first item: */ 361 UIGChooserItem *pFirstParent = selectionList().first()->parentItem(); 362 363 /* Make sure this parent is not main root item: */ 364 if (pFirstParent == mainRoot()) 365 return false; 366 367 /* Enumerate selected set: */ 368 QSet<UIGChooserItem*> selectedSet; 369 foreach (UIGChooserItem *pSelectedItem, selectionList()) 370 selectedSet << pSelectedItem; 371 372 /* Enumerate first parent children set: */ 373 QSet<UIGChooserItem*> firstParentSet; 374 foreach (UIGChooserItem *pSelectedItem, pFirstParent->items()) 375 firstParentSet << pSelectedItem; 376 377 /* Check if both sets contains the same: */ 378 return selectedSet == firstParentSet; 379 } 380 381 UIGChooserItem* UIGChooserModel::focusItem() const 382 { 383 return m_pFocusItem; 384 } 385 386 void UIGChooserModel::setFocusItem(UIGChooserItem *pItem, bool fWithSelection /* = false */) 516 387 { 517 388 /* Make sure real focus unset: */ 518 389 clearRealFocus(); 519 390 520 /* Remember new drag-object: */ 521 m_pCurrentDragObject = pDragObject; 522 connect(m_pCurrentDragObject, SIGNAL(destroyed(QObject*)), this, SLOT(sltCurrentDragObjectDestroyed())); 523 } 524 525 void UIGChooserModel::activate() 526 { 527 gActionPool->action(UIActionIndexSelector_State_Common_StartOrShow)->activate(QAction::Trigger); 391 /* Something changed? */ 392 if (m_pFocusItem != pItem || !pItem) 393 { 394 /* Remember previous focus item: */ 395 QPointer<UIGChooserItem> pPreviousFocusItem = m_pFocusItem; 396 /* Set new focus item: */ 397 m_pFocusItem = pItem; 398 399 /* Should we move selection too? */ 400 if (fWithSelection) 401 { 402 /* Clear selection: */ 403 clearSelectionList(); 404 /* Add focus item into selection (if any): */ 405 if (m_pFocusItem) 406 addToSelectionList(m_pFocusItem); 407 /* Notify selection changed: */ 408 notifySelectionChanged(); 409 } 410 411 /* Update previous focus item (if any): */ 412 if (pPreviousFocusItem) 413 { 414 disconnect(pPreviousFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed())); 415 pPreviousFocusItem->update(); 416 } 417 /* Update new focus item (if any): */ 418 if (m_pFocusItem) 419 { 420 connect(m_pFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed())); 421 m_pFocusItem->update(); 422 } 423 424 /* Notify focus changed: */ 425 emit sigFocusChanged(m_pFocusItem); 426 } 427 } 428 429 UIGChooserItem* UIGChooserModel::mainRoot() const 430 { 431 return m_rootStack.first(); 432 } 433 434 UIGChooserItem* UIGChooserModel::root() const 435 { 436 return m_rootStack.last(); 437 } 438 439 void UIGChooserModel::indentRoot(UIGChooserItem *pNewRootItem) 440 { 441 /* Do nothing is sliding already: */ 442 if (m_fSliding) 443 return; 444 445 /* We are sliding: */ 446 m_fSliding = true; 447 emit sigSlidingStarted(); 448 449 /* Hiding root: */ 450 root()->hide(); 451 452 /* Create left root: */ 453 bool fLeftRootIsMain = root() == mainRoot(); 454 m_pLeftRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), fLeftRootIsMain); 455 m_pLeftRoot->setPos(0, 0); 456 m_pLeftRoot->resize(root()->geometry().size()); 457 458 /* Create right root: */ 459 m_pRightRoot = new UIGChooserItemGroup(scene(), pNewRootItem->toGroupItem(), false); 460 m_pRightRoot->setPos(root()->geometry().width(), 0); 461 m_pRightRoot->resize(root()->geometry().size()); 462 463 /* Indent root: */ 464 m_rootStack << pNewRootItem; 465 root()->setRoot(true); 466 m_pAfterSlidingFocus = root()->items().first(); 467 468 /* Slide root: */ 469 slideRoot(true); 470 } 471 472 void UIGChooserModel::unindentRoot() 473 { 474 /* Do nothing is sliding already: */ 475 if (m_fSliding) 476 return; 477 478 /* We are sliding: */ 479 m_fSliding = true; 480 emit sigSlidingStarted(); 481 482 /* Hiding root: */ 483 root()->hide(); 484 root()->setRoot(false); 485 486 /* Create left root: */ 487 bool fLeftRootIsMain = m_rootStack.at(m_rootStack.size() - 2) == mainRoot(); 488 m_pLeftRoot = new UIGChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem(), fLeftRootIsMain); 489 m_pLeftRoot->setPos(- root()->geometry().width(), 0); 490 m_pLeftRoot->resize(root()->geometry().size()); 491 492 /* Create right root: */ 493 m_pRightRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), false); 494 m_pRightRoot->setPos(0, 0); 495 m_pRightRoot->resize(root()->geometry().size()); 496 497 /* Unindent root: */ 498 m_pAfterSlidingFocus = root(); 499 m_rootStack.removeLast(); 500 501 /* Slide root: */ 502 slideRoot(false); 503 } 504 505 bool UIGChooserModel::isSlidingInProgress() const 506 { 507 return m_fSliding; 528 508 } 529 509 … … 559 539 } 560 540 561 void UIGChooserModel::saveGroupSettings() 562 { 563 emit sigStartGroupSaving(); 564 } 565 566 bool UIGChooserModel::isGroupSavingInProgress() const 567 { 568 return UIGroupDefinitionSaveThread::instance() || 569 UIGroupOrderSaveThread::instance(); 541 void UIGChooserModel::startEditing() 542 { 543 sltStartEditingSelectedGroup(); 544 } 545 546 void UIGChooserModel::updateGroupTree() 547 { 548 updateGroupTree(mainRoot()); 549 } 550 551 void UIGChooserModel::setCurrentDragObject(QDrag *pDragObject) 552 { 553 /* Make sure real focus unset: */ 554 clearRealFocus(); 555 556 /* Remember new drag-object: */ 557 m_pCurrentDragObject = pDragObject; 558 connect(m_pCurrentDragObject, SIGNAL(destroyed(QObject*)), this, SLOT(sltCurrentDragObjectDestroyed())); 570 559 } 571 560 … … 590 579 { 591 580 return m_pLookupTimer->isActive(); 581 } 582 583 void UIGChooserModel::saveGroupSettings() 584 { 585 emit sigStartGroupSaving(); 586 } 587 588 bool UIGChooserModel::isGroupSavingInProgress() const 589 { 590 return UIGroupDefinitionSaveThread::instance() || 591 UIGroupOrderSaveThread::instance(); 592 592 } 593 593 … … 656 656 } 657 657 658 void UIGChooserModel::sltCurrentDragObjectDestroyed() 659 { 660 /* Reset drag tokens starting from the root item: */ 661 root()->resetDragToken(); 662 } 663 664 void UIGChooserModel::sltStartScrolling() 665 { 666 /* Should we scroll? */ 667 if (!m_fIsScrollingInProgress) 668 return; 669 670 /* Reset scrolling progress: */ 671 m_fIsScrollingInProgress = false; 672 673 /* Get view/scrollbar: */ 674 QGraphicsView *pView = scene()->views()[0]; 675 QScrollBar *pVerticalScrollBar = pView->verticalScrollBar(); 676 677 /* Request still valid? */ 678 QPoint mousePos = pView->mapFromGlobal(QCursor::pos()); 679 if (mousePos.y() < m_iScrollingTokenSize) 680 { 681 int iValue = mousePos.y(); 682 if (!iValue) iValue = 1; 683 int iDelta = m_iScrollingTokenSize / iValue; 684 if (pVerticalScrollBar->value() > pVerticalScrollBar->minimum()) 685 { 686 /* Backward scrolling: */ 687 pVerticalScrollBar->setValue(pVerticalScrollBar->value() - 2 * iDelta); 688 m_fIsScrollingInProgress = true; 689 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 690 } 691 } 692 else if (mousePos.y() > pView->height() - m_iScrollingTokenSize) 693 { 694 int iValue = pView->height() - mousePos.y(); 695 if (!iValue) iValue = 1; 696 int iDelta = m_iScrollingTokenSize / iValue; 697 if (pVerticalScrollBar->value() < pVerticalScrollBar->maximum()) 698 { 699 /* Forward scrolling: */ 700 pVerticalScrollBar->setValue(pVerticalScrollBar->value() + 2 * iDelta); 701 m_fIsScrollingInProgress = true; 702 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 703 } 704 } 705 } 706 707 void UIGChooserModel::sltRemoveCurrentlySelectedGroup() 708 { 709 /* Make sure focus item is of group type! */ 710 AssertMsg(focusItem()->type() == UIGChooserItemType_Group, ("This is not group item!")); 711 712 /* Check if we have collisions with our siblings: */ 713 UIGChooserItem *pFocusItem = focusItem(); 714 UIGChooserItem *pParentItem = pFocusItem->parentItem(); 715 QList<UIGChooserItem*> siblings = pParentItem->items(); 716 QList<UIGChooserItem*> toBeRenamed; 717 QList<UIGChooserItem*> toBeRemoved; 718 foreach (UIGChooserItem *pItem, pFocusItem->items()) 719 { 720 QString strItemName = pItem->name(); 721 UIGChooserItem *pCollisionSibling = 0; 722 foreach (UIGChooserItem *pSibling, siblings) 723 if (pSibling != pFocusItem && pSibling->name() == strItemName) 724 pCollisionSibling = pSibling; 725 if (pCollisionSibling) 726 { 727 if (pItem->type() == UIGChooserItemType_Machine) 728 { 729 if (pCollisionSibling->type() == UIGChooserItemType_Machine) 730 toBeRemoved << pItem; 731 else if (pCollisionSibling->type() == UIGChooserItemType_Group) 732 { 733 msgCenter().notifyAboutCollisionOnGroupRemovingCantBeResolved(strItemName, pParentItem->name()); 734 return; 735 } 736 } 737 else if (pItem->type() == UIGChooserItemType_Group) 738 { 739 if (msgCenter().askAboutCollisionOnGroupRemoving(strItemName, pParentItem->name()) == QIMessageBox::Ok) 740 toBeRenamed << pItem; 741 else 742 return; 743 } 744 } 745 } 746 747 /* Copy all the children into our parent: */ 748 foreach (UIGChooserItem *pItem, pFocusItem->items()) 749 { 750 if (toBeRemoved.contains(pItem)) 751 continue; 752 switch (pItem->type()) 753 { 754 case UIGChooserItemType_Group: 755 { 756 UIGChooserItemGroup *pGroupItem = new UIGChooserItemGroup(pParentItem, pItem->toGroupItem()); 757 if (toBeRenamed.contains(pItem)) 758 pGroupItem->setName(uniqueGroupName(pParentItem)); 759 break; 760 } 761 case UIGChooserItemType_Machine: 762 { 763 new UIGChooserItemMachine(pParentItem, pItem->toMachineItem()); 764 break; 765 } 766 } 767 } 768 769 /* Delete focus group: */ 770 delete focusItem(); 771 772 /* And update model: */ 658 void UIGChooserModel::sltFocusItemDestroyed() 659 { 660 AssertMsgFailed(("Focus item destroyed!")); 661 } 662 663 void UIGChooserModel::sltLeftRootSlidingProgress() 664 { 665 /* Update left root: */ 666 m_pLeftRoot->updateSizeHint(); 667 m_pLeftRoot->updateLayout(); 668 } 669 670 void UIGChooserModel::sltRightRootSlidingProgress() 671 { 672 /* Update right root: */ 673 m_pRightRoot->updateSizeHint(); 674 m_pRightRoot->updateLayout(); 675 } 676 677 void UIGChooserModel::sltSlidingComplete() 678 { 679 /* Delete temporary roots: */ 680 delete m_pLeftRoot; 681 m_pLeftRoot = 0; 682 delete m_pRightRoot; 683 m_pRightRoot = 0; 684 685 /* We are no more sliding: */ 686 m_fSliding = false; 687 688 /* Update model: */ 773 689 updateGroupTree(); 774 690 updateNavigation(); 775 691 updateLayout(); 776 if (mainRoot()->hasItems()) 777 setCurrentItem(0); 692 if (m_pAfterSlidingFocus) 693 { 694 setCurrentItem(m_pAfterSlidingFocus); 695 m_pAfterSlidingFocus = 0; 696 } 778 697 else 779 unsetCurrentItem(); 780 saveGroupSettings(); 781 } 782 783 void UIGChooserModel::sltRemoveCurrentlySelectedMachine() 784 { 785 /* Enumerate all the selected machine items: */ 786 QList<UIGChooserItem*> selectedMachineItemList = gatherMachineItems(selectionList()); 787 /* Enumerate all the existing machine items: */ 788 QList<UIGChooserItem*> existingMachineItemList = gatherMachineItems(mainRoot()->items()); 789 790 /* Prepare maps: */ 791 QMap<QString, bool> verdictMap; 792 QMap<QString, QString> namesMap; 793 794 /* For each selected machine item: */ 795 foreach (UIGChooserItem *pItem, selectedMachineItemList) 796 { 797 /* Get item name/id: */ 798 QString strName = pItem->name(); 799 QString strId = pItem->toMachineItem()->id(); 800 801 /* Check if we already decided for that machine: */ 802 if (verdictMap.contains(strId)) 803 continue; 804 805 /* Selected copy count: */ 806 int iSelectedCopyCount = 0; 807 foreach (UIGChooserItem *pSelectedItem, selectedMachineItemList) 808 if (pSelectedItem->toMachineItem()->id() == strId) 809 ++iSelectedCopyCount; 810 811 /* Existing copy count: */ 812 int iExistingCopyCount = 0; 813 foreach (UIGChooserItem *pExistingItem, existingMachineItemList) 814 if (pExistingItem->toMachineItem()->id() == strId) 815 ++iExistingCopyCount; 816 817 /* If selected copy count equal to existing copy count, 818 * we will propose ro unregister machine fully else 819 * we will just propose to remove selected items: */ 820 verdictMap.insert(strId, iSelectedCopyCount == iExistingCopyCount); 821 namesMap.insert(strId, strName); 822 } 823 824 /* If we have something to remove: */ 825 if (verdictMap.values().contains(false)) 826 { 827 /* Gather names: */ 828 QStringList names; 829 foreach (const QString &strId, verdictMap.keys()) 830 if (!verdictMap[strId]) 831 names << namesMap[strId]; 832 removeMachineItems(names, selectedMachineItemList); 833 } 834 /* If we have something to unregister: */ 835 if (verdictMap.values().contains(true)) 836 { 837 /* Gather ids: */ 838 QStringList ids; 839 foreach (const QString &strId, verdictMap.keys()) 840 if (verdictMap[strId]) 841 ids << strId; 842 unregisterMachines(ids); 698 { 699 if (root()->hasItems()) 700 setCurrentItem(root()->items().first()); 701 else 702 unsetCurrentItem(); 843 703 } 844 704 } … … 905 765 } 906 766 767 void UIGChooserModel::sltSortGroup() 768 { 769 if (isSingleGroupSelected()) 770 sortItems(selectionList().first()); 771 } 772 773 void UIGChooserModel::sltRemoveCurrentlySelectedGroup() 774 { 775 /* Make sure focus item is of group type! */ 776 AssertMsg(focusItem()->type() == UIGChooserItemType_Group, ("This is not group item!")); 777 778 /* Check if we have collisions with our siblings: */ 779 UIGChooserItem *pFocusItem = focusItem(); 780 UIGChooserItem *pParentItem = pFocusItem->parentItem(); 781 QList<UIGChooserItem*> siblings = pParentItem->items(); 782 QList<UIGChooserItem*> toBeRenamed; 783 QList<UIGChooserItem*> toBeRemoved; 784 foreach (UIGChooserItem *pItem, pFocusItem->items()) 785 { 786 QString strItemName = pItem->name(); 787 UIGChooserItem *pCollisionSibling = 0; 788 foreach (UIGChooserItem *pSibling, siblings) 789 if (pSibling != pFocusItem && pSibling->name() == strItemName) 790 pCollisionSibling = pSibling; 791 if (pCollisionSibling) 792 { 793 if (pItem->type() == UIGChooserItemType_Machine) 794 { 795 if (pCollisionSibling->type() == UIGChooserItemType_Machine) 796 toBeRemoved << pItem; 797 else if (pCollisionSibling->type() == UIGChooserItemType_Group) 798 { 799 msgCenter().notifyAboutCollisionOnGroupRemovingCantBeResolved(strItemName, pParentItem->name()); 800 return; 801 } 802 } 803 else if (pItem->type() == UIGChooserItemType_Group) 804 { 805 if (msgCenter().askAboutCollisionOnGroupRemoving(strItemName, pParentItem->name()) == QIMessageBox::Ok) 806 toBeRenamed << pItem; 807 else 808 return; 809 } 810 } 811 } 812 813 /* Copy all the children into our parent: */ 814 foreach (UIGChooserItem *pItem, pFocusItem->items()) 815 { 816 if (toBeRemoved.contains(pItem)) 817 continue; 818 switch (pItem->type()) 819 { 820 case UIGChooserItemType_Group: 821 { 822 UIGChooserItemGroup *pGroupItem = new UIGChooserItemGroup(pParentItem, pItem->toGroupItem()); 823 if (toBeRenamed.contains(pItem)) 824 pGroupItem->setName(uniqueGroupName(pParentItem)); 825 break; 826 } 827 case UIGChooserItemType_Machine: 828 { 829 new UIGChooserItemMachine(pParentItem, pItem->toMachineItem()); 830 break; 831 } 832 } 833 } 834 835 /* Delete focus group: */ 836 delete focusItem(); 837 838 /* And update model: */ 839 updateGroupTree(); 840 updateNavigation(); 841 updateLayout(); 842 if (mainRoot()->hasItems()) 843 setCurrentItem(0); 844 else 845 unsetCurrentItem(); 846 saveGroupSettings(); 847 } 848 907 849 void UIGChooserModel::sltCreateNewMachine() 908 850 { … … 922 864 } 923 865 924 void UIGChooserModel::sltActionHovered(QAction *pAction) 925 { 926 emit sigShowStatusMessage(pAction->statusTip()); 927 } 928 929 void UIGChooserModel::sltFocusItemDestroyed() 930 { 931 AssertMsgFailed(("Focus item destroyed!")); 932 } 933 934 void UIGChooserModel::sltLeftRootSlidingProgress() 935 { 936 /* Update left root: */ 937 m_pLeftRoot->updateSizeHint(); 938 m_pLeftRoot->updateLayout(); 939 } 940 941 void UIGChooserModel::sltRightRootSlidingProgress() 942 { 943 /* Update right root: */ 944 m_pRightRoot->updateSizeHint(); 945 m_pRightRoot->updateLayout(); 946 } 947 948 void UIGChooserModel::sltSlidingComplete() 949 { 950 /* Delete temporary roots: */ 951 delete m_pLeftRoot; 952 m_pLeftRoot = 0; 953 delete m_pRightRoot; 954 m_pRightRoot = 0; 955 956 /* We are no more sliding: */ 957 m_fSliding = false; 958 959 /* Update model: */ 866 void UIGChooserModel::sltReloadMachine(const QString &strId) 867 { 868 /* Remove all the items first: */ 869 removeMachineItems(strId, mainRoot()); 870 871 /* Check if such machine still present: */ 872 CMachine machine = vboxGlobal().virtualBox().FindMachine(strId); 873 if (machine.isNull()) 874 return; 875 876 /* Add machine into the tree: */ 877 addMachineIntoTheTree(machine); 878 879 /* And update model: */ 960 880 updateGroupTree(); 961 881 updateNavigation(); 962 882 updateLayout(); 963 if (m_pAfterSlidingFocus) 964 { 965 setCurrentItem(m_pAfterSlidingFocus); 966 m_pAfterSlidingFocus = 0; 967 } 968 else 969 { 970 if (root()->hasItems()) 971 setCurrentItem(root()->items().first()); 972 else 973 unsetCurrentItem(); 974 } 883 884 /* Notify listeners about selection change: */ 885 emit sigSelectionChanged(); 886 } 887 888 void UIGChooserModel::sltSortParentGroup() 889 { 890 if (!selectionList().isEmpty()) 891 sortItems(selectionList().first()->parentItem()); 975 892 } 976 893 … … 1008 925 } 1009 926 1010 void UIGChooserModel::sltSortParentGroup() 1011 { 1012 if (!selectionList().isEmpty()) 1013 sortItems(selectionList().first()->parentItem()); 1014 } 1015 1016 void UIGChooserModel::sltSortGroup() 1017 { 1018 if (isSingleGroupSelected()) 1019 sortItems(selectionList().first()); 927 void UIGChooserModel::sltRemoveCurrentlySelectedMachine() 928 { 929 /* Enumerate all the selected machine items: */ 930 QList<UIGChooserItem*> selectedMachineItemList = gatherMachineItems(selectionList()); 931 /* Enumerate all the existing machine items: */ 932 QList<UIGChooserItem*> existingMachineItemList = gatherMachineItems(mainRoot()->items()); 933 934 /* Prepare maps: */ 935 QMap<QString, bool> verdictMap; 936 QMap<QString, QString> namesMap; 937 938 /* For each selected machine item: */ 939 foreach (UIGChooserItem *pItem, selectedMachineItemList) 940 { 941 /* Get item name/id: */ 942 QString strName = pItem->name(); 943 QString strId = pItem->toMachineItem()->id(); 944 945 /* Check if we already decided for that machine: */ 946 if (verdictMap.contains(strId)) 947 continue; 948 949 /* Selected copy count: */ 950 int iSelectedCopyCount = 0; 951 foreach (UIGChooserItem *pSelectedItem, selectedMachineItemList) 952 if (pSelectedItem->toMachineItem()->id() == strId) 953 ++iSelectedCopyCount; 954 955 /* Existing copy count: */ 956 int iExistingCopyCount = 0; 957 foreach (UIGChooserItem *pExistingItem, existingMachineItemList) 958 if (pExistingItem->toMachineItem()->id() == strId) 959 ++iExistingCopyCount; 960 961 /* If selected copy count equal to existing copy count, 962 * we will propose ro unregister machine fully else 963 * we will just propose to remove selected items: */ 964 verdictMap.insert(strId, iSelectedCopyCount == iExistingCopyCount); 965 namesMap.insert(strId, strName); 966 } 967 968 /* If we have something to remove: */ 969 if (verdictMap.values().contains(false)) 970 { 971 /* Gather names: */ 972 QStringList names; 973 foreach (const QString &strId, verdictMap.keys()) 974 if (!verdictMap[strId]) 975 names << namesMap[strId]; 976 removeMachineItems(names, selectedMachineItemList); 977 } 978 /* If we have something to unregister: */ 979 if (verdictMap.values().contains(true)) 980 { 981 /* Gather ids: */ 982 QStringList ids; 983 foreach (const QString &strId, verdictMap.keys()) 984 if (verdictMap[strId]) 985 ids << strId; 986 unregisterMachines(ids); 987 } 988 } 989 990 void UIGChooserModel::sltStartScrolling() 991 { 992 /* Should we scroll? */ 993 if (!m_fIsScrollingInProgress) 994 return; 995 996 /* Reset scrolling progress: */ 997 m_fIsScrollingInProgress = false; 998 999 /* Get view/scrollbar: */ 1000 QGraphicsView *pView = scene()->views()[0]; 1001 QScrollBar *pVerticalScrollBar = pView->verticalScrollBar(); 1002 1003 /* Request still valid? */ 1004 QPoint mousePos = pView->mapFromGlobal(QCursor::pos()); 1005 if (mousePos.y() < m_iScrollingTokenSize) 1006 { 1007 int iValue = mousePos.y(); 1008 if (!iValue) iValue = 1; 1009 int iDelta = m_iScrollingTokenSize / iValue; 1010 if (pVerticalScrollBar->value() > pVerticalScrollBar->minimum()) 1011 { 1012 /* Backward scrolling: */ 1013 pVerticalScrollBar->setValue(pVerticalScrollBar->value() - 2 * iDelta); 1014 m_fIsScrollingInProgress = true; 1015 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 1016 } 1017 } 1018 else if (mousePos.y() > pView->height() - m_iScrollingTokenSize) 1019 { 1020 int iValue = pView->height() - mousePos.y(); 1021 if (!iValue) iValue = 1; 1022 int iDelta = m_iScrollingTokenSize / iValue; 1023 if (pVerticalScrollBar->value() < pVerticalScrollBar->maximum()) 1024 { 1025 /* Forward scrolling: */ 1026 pVerticalScrollBar->setValue(pVerticalScrollBar->value() + 2 * iDelta); 1027 m_fIsScrollingInProgress = true; 1028 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 1029 } 1030 } 1031 } 1032 1033 void UIGChooserModel::sltCurrentDragObjectDestroyed() 1034 { 1035 /* Reset drag tokens starting from the root item: */ 1036 root()->resetDragToken(); 1037 } 1038 1039 void UIGChooserModel::sltActionHovered(QAction *pAction) 1040 { 1041 emit sigShowStatusMessage(pAction->statusTip()); 1042 } 1043 1044 void UIGChooserModel::sltEraseLookupTimer() 1045 { 1046 m_pLookupTimer->stop(); 1047 m_strLookupString = QString(); 1020 1048 } 1021 1049 … … 1036 1064 makeSureGroupOrdersSaveIsFinished(); 1037 1065 emit sigGroupSavingStateChanged(); 1038 }1039 1040 void UIGChooserModel::sltReloadMachine(const QString &strId)1041 {1042 /* Remove all the items first: */1043 removeMachineItems(strId, mainRoot());1044 1045 /* Check if such machine still present: */1046 CMachine machine = vboxGlobal().virtualBox().FindMachine(strId);1047 if (machine.isNull())1048 return;1049 1050 /* Add machine into the tree: */1051 addMachineIntoTheTree(machine);1052 1053 /* And update model: */1054 updateGroupTree();1055 updateNavigation();1056 updateLayout();1057 1058 /* Notify listeners about selection change: */1059 emit sigSelectionChanged();1060 }1061 1062 void UIGChooserModel::sltEraseLookupTimer()1063 {1064 m_pLookupTimer->stop();1065 m_strLookupString = QString();1066 1066 } 1067 1067 … … 1319 1319 } 1320 1320 1321 void UIGChooserModel::clearRealFocus() 1322 { 1323 /* Set real focus to null: */ 1324 scene()->setFocusItem(0); 1321 QList<UIGChooserItem*> UIGChooserModel::createNavigationList(UIGChooserItem *pItem) 1322 { 1323 /* Prepare navigation list: */ 1324 QList<UIGChooserItem*> navigationItems; 1325 1326 /* Iterate over all the group items: */ 1327 foreach (UIGChooserItem *pGroupItem, pItem->items(UIGChooserItemType_Group)) 1328 { 1329 navigationItems << pGroupItem; 1330 if (pGroupItem->toGroupItem()->opened()) 1331 navigationItems << createNavigationList(pGroupItem); 1332 } 1333 /* Iterate over all the machine items: */ 1334 foreach (UIGChooserItem *pMachineItem, pItem->items(UIGChooserItemType_Machine)) 1335 navigationItems << pMachineItem; 1336 1337 /* Return navigation list: */ 1338 return navigationItems; 1325 1339 } 1326 1340 … … 1384 1398 } 1385 1399 1386 void UIGChooserModel::loadGroupTree() 1387 { 1388 /* Add all the machines we have into the group-tree: */ 1389 LogRel(("Loading VMs started...\n")); 1390 foreach (const CMachine &machine, vboxGlobal().virtualBox().GetMachines()) 1391 addMachineIntoTheTree(machine); 1392 LogRel(("Loading VMs finished.\n")); 1393 } 1394 1395 void UIGChooserModel::addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible /* = false */) 1396 { 1397 /* Which VM we are loading: */ 1398 if (machine.isNull()) 1399 LogRel((" ERROR: VM is NULL!\n")); 1400 else 1401 LogRel((" Loading VM {%s}...\n", machine.GetId().toAscii().constData())); 1402 /* Is that machine accessible? */ 1403 if (machine.GetAccessible()) 1404 { 1405 /* VM is accessible: */ 1406 QString strName = machine.GetName(); 1407 LogRel((" VM {%s} is accessible.\n", strName.toAscii().constData())); 1408 /* Which groups passed machine attached to? */ 1409 QVector<QString> groups = machine.GetGroups(); 1410 QStringList groupList = groups.toList(); 1411 QString strGroups = groupList.join(", "); 1412 LogRel((" VM {%s} groups are {%s}.\n", strName.toAscii().constData(), 1413 strGroups.toAscii().constData())); 1414 foreach (QString strGroup, groups) 1415 { 1416 /* Remove last '/' if any: */ 1417 if (strGroup.right(1) == "/") 1418 strGroup.truncate(strGroup.size() - 1); 1419 /* Create machine item with found group item as parent: */ 1420 LogRel((" Creating item for VM {%s}, group {%s}.\n", strName.toAscii().constData(), 1421 strGroup.toAscii().constData())); 1422 createMachineItem(machine, getGroupItem(strGroup, mainRoot(), fMakeItVisible)); 1423 } 1424 /* Update group definitions: */ 1425 m_groups[machine.GetId()] = groupList; 1426 } 1427 /* Inaccessible machine: */ 1428 else 1429 { 1430 /* VM is accessible: */ 1431 LogRel((" VM {%s} is inaccessible.\n", machine.GetId().toAscii().constData())); 1432 /* Create machine item with main-root group item as parent: */ 1433 createMachineItem(machine, mainRoot()); 1434 } 1435 } 1436 1437 UIGChooserItem* UIGChooserModel::getGroupItem(const QString &strName, UIGChooserItem *pParentItem, bool fAllGroupsOpened) 1438 { 1439 /* Check passed stuff: */ 1440 if (pParentItem->name() == strName) 1441 return pParentItem; 1442 1443 /* Prepare variables: */ 1444 QString strFirstSubName = strName.section('/', 0, 0); 1445 QString strFirstSuffix = strName.section('/', 1, -1); 1446 QString strSecondSubName = strFirstSuffix.section('/', 0, 0); 1447 QString strSecondSuffix = strFirstSuffix.section('/', 1, -1); 1448 1449 /* Passed group name equal to first sub-name: */ 1450 if (pParentItem->name() == strFirstSubName) 1451 { 1452 /* Make sure first-suffix is NOT empty: */ 1453 AssertMsg(!strFirstSuffix.isEmpty(), ("Invalid group name!")); 1454 /* Trying to get group item among our children: */ 1455 foreach (UIGChooserItem *pGroupItem, pParentItem->items(UIGChooserItemType_Group)) 1456 { 1457 if (pGroupItem->name() == strSecondSubName) 1458 { 1459 UIGChooserItem *pFoundItem = getGroupItem(strFirstSuffix, pGroupItem, fAllGroupsOpened); 1460 if (UIGChooserItemGroup *pFoundGroupItem = pFoundItem->toGroupItem()) 1461 if (fAllGroupsOpened && pFoundGroupItem->closed()) 1462 pFoundGroupItem->open(false); 1463 return pFoundItem; 1464 } 1465 } 1466 } 1467 1468 /* Found nothing? Creating: */ 1469 UIGChooserItemGroup *pNewGroupItem = 1470 new UIGChooserItemGroup(/* Parent item and desired group name: */ 1471 pParentItem, strSecondSubName, 1472 /* Should be new group opened when created? */ 1473 fAllGroupsOpened || shouldBeGroupOpened(pParentItem, strSecondSubName), 1474 /* Which position new group item should be placed in? */ 1475 getDesiredPosition(pParentItem, UIGChooserItemType_Group, strSecondSubName)); 1476 return strSecondSuffix.isEmpty() ? pNewGroupItem : getGroupItem(strFirstSuffix, pNewGroupItem, fAllGroupsOpened); 1477 } 1478 1479 bool UIGChooserModel::shouldBeGroupOpened(UIGChooserItem *pParentItem, const QString &strName) 1480 { 1481 /* Prepare extra-data key for the parent-item: */ 1482 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 1483 /* Read group definitions: */ 1484 QStringList definitions = vboxGlobal().virtualBox().GetExtraDataStringList(strExtraDataKey); 1485 /* Return 'false' if no definitions found: */ 1486 if (definitions.isEmpty()) 1487 return false; 1488 1489 /* Prepare required group definition reg-exp: */ 1490 QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName); 1491 QRegExp definitionRegExp(strDefinitionTemplate); 1492 /* For each the group definition: */ 1493 for (int i = 0; i < definitions.size(); ++i) 1494 { 1495 /* Get current definition: */ 1496 const QString &strDefinition = definitions[i]; 1497 /* Check if this is required definition: */ 1498 if (definitionRegExp.indexIn(strDefinition) == 0) 1499 { 1500 /* Get group descriptor: */ 1501 QString strDescriptor(definitionRegExp.cap(1)); 1502 if (strDescriptor.contains('o')) 1503 return true; 1504 } 1505 } 1506 1507 /* Return 'false' by default: */ 1508 return false; 1509 } 1510 1511 int UIGChooserModel::getDesiredPosition(UIGChooserItem *pParentItem, UIGChooserItemType type, const QString &strName) 1512 { 1513 /* End of list (by default)? */ 1514 int iNewItemDesiredPosition = -1; 1515 /* Which position should be new item placed by definitions: */ 1516 int iNewItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strName); 1517 /* If some position wanted: */ 1518 if (iNewItemDefinitionPosition != -1) 1519 { 1520 /* Start of list if some definition present: */ 1521 iNewItemDesiredPosition = 0; 1522 /* We have to check all the existing item positions: */ 1523 QList<UIGChooserItem*> items = pParentItem->items(type); 1524 for (int i = items.size() - 1; i >= 0; --i) 1525 { 1526 /* Get current item: */ 1527 UIGChooserItem *pItem = items[i]; 1528 /* Which position should be current item placed by definitions? */ 1529 QString strDefinitionName = pItem->type() == UIGChooserItemType_Group ? pItem->name() : 1530 pItem->type() == UIGChooserItemType_Machine ? pItem->toMachineItem()->id() : 1531 QString(); 1532 AssertMsg(!strDefinitionName.isEmpty(), ("Wrong definition name!")); 1533 int iItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strDefinitionName); 1534 /* If some position wanted: */ 1535 if (iItemDefinitionPosition != -1) 1536 { 1537 AssertMsg(iItemDefinitionPosition != iNewItemDefinitionPosition, ("Incorrect definitions!")); 1538 if (iItemDefinitionPosition < iNewItemDefinitionPosition) 1539 { 1540 iNewItemDesiredPosition = i + 1; 1541 break; 1542 } 1543 } 1544 } 1545 } 1546 /* Return desired item position: */ 1547 return iNewItemDesiredPosition; 1548 } 1549 1550 int UIGChooserModel::positionFromDefinitions(UIGChooserItem *pParentItem, UIGChooserItemType type, const QString &strName) 1551 { 1552 /* Prepare extra-data key for the parent-item: */ 1553 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 1554 /* Read group definitions: */ 1555 QStringList definitions = vboxGlobal().virtualBox().GetExtraDataStringList(strExtraDataKey); 1556 /* Return 'false' if no definitions found: */ 1557 if (definitions.isEmpty()) 1558 return -1; 1559 1560 /* Prepare definition reg-exp: */ 1561 QString strDefinitionTemplateShort; 1562 QString strDefinitionTemplateFull; 1563 switch (type) 1564 { 1565 case UIGChooserItemType_Group: 1566 strDefinitionTemplateShort = QString("^g(\\S)*="); 1567 strDefinitionTemplateFull = QString("^g(\\S)*=%1$").arg(strName); 1568 break; 1569 case UIGChooserItemType_Machine: 1570 strDefinitionTemplateShort = QString("^m="); 1571 strDefinitionTemplateFull = QString("^m=%1$").arg(strName); 1572 break; 1573 default: return -1; 1574 } 1575 QRegExp definitionRegExpShort(strDefinitionTemplateShort); 1576 QRegExp definitionRegExpFull(strDefinitionTemplateFull); 1577 1578 /* For each the definition: */ 1579 int iDefinitionIndex = -1; 1580 for (int i = 0; i < definitions.size(); ++i) 1581 { 1582 /* Get current definition: */ 1583 QString strDefinition = definitions[i]; 1584 /* Check if this definition is of required type: */ 1585 if (definitionRegExpShort.indexIn(strDefinition) == 0) 1586 { 1587 ++iDefinitionIndex; 1588 /* Check if this definition is exactly what we need: */ 1589 if (definitionRegExpFull.indexIn(strDefinition) == 0) 1590 return iDefinitionIndex; 1591 } 1592 } 1593 1594 /* Return result: */ 1595 return -1; 1596 } 1597 1598 void UIGChooserModel::createMachineItem(const CMachine &machine, UIGChooserItem *pParentItem) 1599 { 1600 /* Create corresponding item: */ 1601 new UIGChooserItemMachine(/* Parent item and corresponding machine: */ 1602 pParentItem, machine, 1603 /* Which position new group item should be placed in? */ 1604 getDesiredPosition(pParentItem, UIGChooserItemType_Machine, machine.GetId())); 1605 } 1606 1607 void UIGChooserModel::saveGroupDefinitions() 1608 { 1609 /* Make sure there is no group save activity: */ 1610 if (UIGroupDefinitionSaveThread::instance()) 1611 return; 1612 1613 /* Prepare full group map: */ 1614 QMap<QString, QStringList> groups; 1615 gatherGroupDefinitions(groups, mainRoot()); 1616 1617 /* Save information in other thread: */ 1618 UIGroupDefinitionSaveThread::prepare(); 1619 emit sigGroupSavingStateChanged(); 1620 connect(UIGroupDefinitionSaveThread::instance(), SIGNAL(sigReload(QString)), 1621 this, SLOT(sltReloadMachine(QString))); 1622 UIGroupDefinitionSaveThread::instance()->configure(this, m_groups, groups); 1623 UIGroupDefinitionSaveThread::instance()->start(); 1624 m_groups = groups; 1625 } 1626 1627 void UIGChooserModel::saveGroupOrders() 1628 { 1629 /* Make sure there is no group save activity: */ 1630 if (UIGroupOrderSaveThread::instance()) 1631 return; 1632 1633 /* Prepare full group map: */ 1634 QMap<QString, QStringList> groups; 1635 gatherGroupOrders(groups, mainRoot()); 1636 1637 /* Save information in other thread: */ 1638 UIGroupOrderSaveThread::prepare(); 1639 emit sigGroupSavingStateChanged(); 1640 UIGroupOrderSaveThread::instance()->configure(this, groups); 1641 UIGroupOrderSaveThread::instance()->start(); 1642 } 1643 1644 void UIGChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &groups, 1645 UIGChooserItem *pParentGroup) 1646 { 1647 /* Iterate over all the machine items: */ 1648 foreach (UIGChooserItem *pItem, pParentGroup->items(UIGChooserItemType_Machine)) 1649 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem()) 1650 if (pMachineItem->accessible()) 1651 groups[pMachineItem->id()] << fullName(pParentGroup); 1652 /* Iterate over all the group items: */ 1653 foreach (UIGChooserItem *pItem, pParentGroup->items(UIGChooserItemType_Group)) 1654 gatherGroupDefinitions(groups, pItem); 1655 } 1656 1657 void UIGChooserModel::gatherGroupOrders(QMap<QString, QStringList> &groups, 1658 UIGChooserItem *pParentItem) 1659 { 1660 /* Prepare extra-data key for current group: */ 1661 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 1662 /* Iterate over all the group items: */ 1663 foreach (UIGChooserItem *pItem, pParentItem->items(UIGChooserItemType_Group)) 1664 { 1665 QString strGroupDescriptor(pItem->toGroupItem()->opened() ? "go" : "gc"); 1666 groups[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name()); 1667 gatherGroupOrders(groups, pItem); 1668 } 1669 /* Iterate over all the machine items: */ 1670 foreach (UIGChooserItem *pItem, pParentItem->items(UIGChooserItemType_Machine)) 1671 groups[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id()); 1672 } 1673 1674 QString UIGChooserModel::fullName(UIGChooserItem *pItem) 1675 { 1676 /* Return '/' for root-group: */ 1677 if (!pItem->parentItem()) 1678 return QString("/"); 1679 /* Get full parent name, append with '/' if not yet appended: */ 1680 QString strParentFullName = fullName(pItem->parentItem()); 1681 if (!strParentFullName.endsWith("/")) 1682 strParentFullName += QString("/"); 1683 /* Return full item name based on parent prefix: */ 1684 return strParentFullName + pItem->name(); 1400 void UIGChooserModel::clearRealFocus() 1401 { 1402 /* Set real focus to null: */ 1403 scene()->setFocusItem(0); 1404 } 1405 1406 void UIGChooserModel::slideRoot(bool fForward) 1407 { 1408 /* Animation group: */ 1409 QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this); 1410 connect(pAnimation, SIGNAL(finished()), this, SLOT(sltSlidingComplete()), Qt::QueuedConnection); 1411 1412 /* Left root animation: */ 1413 { 1414 QPropertyAnimation *pLeftAnimation = new QPropertyAnimation(m_pLeftRoot, "geometry", this); 1415 connect(pLeftAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltLeftRootSlidingProgress())); 1416 QRectF startGeo = m_pLeftRoot->geometry(); 1417 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) : 1418 startGeo.translated(startGeo.width(), 0); 1419 pLeftAnimation->setEasingCurve(QEasingCurve::InCubic); 1420 pLeftAnimation->setDuration(500); 1421 pLeftAnimation->setStartValue(startGeo); 1422 pLeftAnimation->setEndValue(endGeo); 1423 pAnimation->addAnimation(pLeftAnimation); 1424 } 1425 1426 /* Right root animation: */ 1427 { 1428 QPropertyAnimation *pRightAnimation = new QPropertyAnimation(m_pRightRoot, "geometry", this); 1429 connect(pRightAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltRightRootSlidingProgress())); 1430 QRectF startGeo = m_pRightRoot->geometry(); 1431 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) : 1432 startGeo.translated(startGeo.width(), 0); 1433 pRightAnimation->setEasingCurve(QEasingCurve::InCubic); 1434 pRightAnimation->setDuration(500); 1435 pRightAnimation->setStartValue(startGeo); 1436 pRightAnimation->setEndValue(endGeo); 1437 pAnimation->addAnimation(pRightAnimation); 1438 } 1439 1440 /* Start animation: */ 1441 pAnimation->start(); 1442 } 1443 1444 UIGChooserItem* UIGChooserModel::findGroupItem(const QString &strName, UIGChooserItem *pParent) 1445 { 1446 /* Search among all the group items of passed parent: */ 1447 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1448 if (pGroupItem->name() == strName) 1449 return pGroupItem; 1450 /* Recursively iterate into each the group item of the passed parent: */ 1451 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1452 if (UIGChooserItem *pSubGroupItem = findGroupItem(strName, pGroupItem)) 1453 return pSubGroupItem; 1454 /* Nothing found? */ 1455 return 0; 1685 1456 } 1686 1457 … … 1701 1472 } 1702 1473 1703 QList<UIGChooserItem*> UIGChooserModel::createNavigationList(UIGChooserItem *pItem) 1704 { 1705 /* Prepare navigation list: */ 1706 QList<UIGChooserItem*> navigationItems; 1707 1708 /* Iterate over all the group items: */ 1709 foreach (UIGChooserItem *pGroupItem, pItem->items(UIGChooserItemType_Group)) 1710 { 1711 navigationItems << pGroupItem; 1712 if (pGroupItem->toGroupItem()->opened()) 1713 navigationItems << createNavigationList(pGroupItem); 1714 } 1715 /* Iterate over all the machine items: */ 1716 foreach (UIGChooserItem *pMachineItem, pItem->items(UIGChooserItemType_Machine)) 1717 navigationItems << pMachineItem; 1718 1719 /* Return navigation list: */ 1720 return navigationItems; 1474 UIGChooserItem* UIGChooserModel::findMachineItem(const QString &strName, UIGChooserItem *pParent) 1475 { 1476 /* Search among all the machine items of passed parent: */ 1477 foreach (UIGChooserItem *pMachineItem, pParent->items(UIGChooserItemType_Machine)) 1478 if (pMachineItem->name() == strName) 1479 return pMachineItem; 1480 /* Recursively iterate into each the group item of the passed parent: */ 1481 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1482 if (UIGChooserItem *pSubMachineItem = findMachineItem(strName, pGroupItem)) 1483 return pSubMachineItem; 1484 /* Nothing found? */ 1485 return 0; 1486 } 1487 1488 QList<UIGChooserItem*> UIGChooserModel::gatherMachineItems(const QList<UIGChooserItem*> &selectedItems) const 1489 { 1490 QList<UIGChooserItem*> machineItems; 1491 foreach (UIGChooserItem *pItem, selectedItems) 1492 { 1493 if (pItem->type() == UIGChooserItemType_Machine) 1494 machineItems << pItem; 1495 if (pItem->type() == UIGChooserItemType_Group) 1496 machineItems << gatherMachineItems(pItem->items()); 1497 } 1498 return machineItems; 1499 } 1500 1501 void UIGChooserModel::enumerateInaccessibleItems(const QList<UIGChooserItem*> &il, QList<UIGChooserItem*> &ol) const 1502 { 1503 /* Enumerate all the passed items: */ 1504 foreach (UIGChooserItem *pItem, il) 1505 { 1506 /* If item is inaccessible machine: */ 1507 if (pItem->type() == UIGChooserItemType_Machine) 1508 { 1509 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem()) 1510 if (!pMachineItem->accessible() && !contains(ol, pItem)) 1511 ol << pMachineItem; 1512 } 1513 /* If item is group: */ 1514 else if (pItem->type() == UIGChooserItemType_Group) 1515 { 1516 /* Enumerate all the machine items recursively: */ 1517 enumerateInaccessibleItems(pItem->items(UIGChooserItemType_Machine), ol); 1518 /* Enumerate all the group items recursively: */ 1519 enumerateInaccessibleItems(pItem->items(UIGChooserItemType_Group), ol); 1520 } 1521 } 1522 } 1523 1524 bool UIGChooserModel::contains(const QList<UIGChooserItem*> &il, UIGChooserItem *pLookupItem) const 1525 { 1526 /* We assume passed list contains only machine items: */ 1527 foreach (UIGChooserItem *pItem, il) 1528 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem()) 1529 if (pMachineItem->id() == pLookupItem->toMachineItem()->id()) 1530 return true; 1531 return false; 1532 } 1533 1534 void UIGChooserModel::sortItems(UIGChooserItem *pParent, bool fRecursively /* = false */) 1535 { 1536 /* Sort group items: */ 1537 QMap<QString, UIGChooserItem*> sorter; 1538 foreach (UIGChooserItem *pItem, pParent->items(UIGChooserItemType_Group)) 1539 { 1540 sorter.insert(pItem->name().toLower(), pItem); 1541 if (fRecursively) 1542 sortItems(pItem, fRecursively); 1543 } 1544 pParent->setItems(sorter.values(), UIGChooserItemType_Group); 1545 1546 /* Sort machine items: */ 1547 sorter.clear(); 1548 foreach (UIGChooserItem *pItem, pParent->items(UIGChooserItemType_Machine)) 1549 sorter.insert(pItem->name().toLower(), pItem); 1550 pParent->setItems(sorter.values(), UIGChooserItemType_Machine); 1551 1552 /* Update model: */ 1553 updateNavigation(); 1554 updateLayout(); 1721 1555 } 1722 1556 … … 1753 1587 } 1754 1588 1755 UIGChooserItem* UIGChooserModel::findGroupItem(const QString &strName, UIGChooserItem *pParent) 1756 { 1757 /* Search among all the group items of passed parent: */ 1758 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1759 if (pGroupItem->name() == strName) 1760 return pGroupItem; 1761 /* Recursively iterate into each the group item of the passed parent: */ 1762 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1763 if (UIGChooserItem *pSubGroupItem = findGroupItem(strName, pGroupItem)) 1764 return pSubGroupItem; 1765 /* Nothing found? */ 1766 return 0; 1767 } 1768 1769 UIGChooserItem* UIGChooserModel::findMachineItem(const QString &strName, UIGChooserItem *pParent) 1770 { 1771 /* Search among all the machine items of passed parent: */ 1772 foreach (UIGChooserItem *pMachineItem, pParent->items(UIGChooserItemType_Machine)) 1773 if (pMachineItem->name() == strName) 1774 return pMachineItem; 1775 /* Recursively iterate into each the group item of the passed parent: */ 1776 foreach (UIGChooserItem *pGroupItem, pParent->items(UIGChooserItemType_Group)) 1777 if (UIGChooserItem *pSubMachineItem = findMachineItem(strName, pGroupItem)) 1778 return pSubMachineItem; 1779 /* Nothing found? */ 1780 return 0; 1589 void UIGChooserModel::removeMachineItems(const QStringList &names, QList<UIGChooserItem*> &selectedItems) 1590 { 1591 /* Show machine items remove dialog: */ 1592 int rc = msgCenter().confirmMachineItemRemoval(names); 1593 if (rc == QIMessageBox::Cancel) 1594 return; 1595 1596 /* Remove all the required items: */ 1597 foreach (UIGChooserItem *pItem, selectedItems) 1598 if (names.contains(pItem->name())) 1599 delete pItem; 1600 1601 /* And update model: */ 1602 updateGroupTree(); 1603 updateNavigation(); 1604 updateLayout(); 1605 if (mainRoot()->hasItems()) 1606 setCurrentItem(0); 1607 else 1608 unsetCurrentItem(); 1609 saveGroupSettings(); 1610 } 1611 1612 void UIGChooserModel::unregisterMachines(const QStringList &ids) 1613 { 1614 /* Populate machine list: */ 1615 QList<CMachine> machines; 1616 CVirtualBox vbox = vboxGlobal().virtualBox(); 1617 foreach (const QString &strId, ids) 1618 { 1619 CMachine machine = vbox.FindMachine(strId); 1620 if (!machine.isNull()) 1621 machines << machine; 1622 } 1623 1624 /* Show machine remove dialog: */ 1625 int rc = msgCenter().confirmMachineDeletion(machines); 1626 if (rc != QIMessageBox::Cancel) 1627 { 1628 /* For every selected item: */ 1629 foreach (CMachine machine, machines) 1630 { 1631 if (rc == QIMessageBox::Yes) 1632 { 1633 /* Unregister and cleanup machine's data & hard-disks: */ 1634 CMediumVector mediums = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly); 1635 if (machine.isOk()) 1636 { 1637 /* Delete machine hard-disks: */ 1638 CProgress progress = machine.Delete(mediums); 1639 if (machine.isOk()) 1640 { 1641 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png", 0, true); 1642 if (progress.GetResultCode() != 0) 1643 msgCenter().cannotDeleteMachine(machine, progress); 1644 } 1645 } 1646 if (!machine.isOk()) 1647 msgCenter().cannotDeleteMachine(machine); 1648 } 1649 else 1650 { 1651 /* Just unregister machine: */ 1652 machine.Unregister(KCleanupMode_DetachAllReturnNone); 1653 if (!machine.isOk()) 1654 msgCenter().cannotDeleteMachine(machine); 1655 } 1656 } 1657 } 1781 1658 } 1782 1659 … … 1904 1781 } 1905 1782 1906 void UIGChooserModel::slideRoot(bool fForward)1907 {1908 /* Animation group: */1909 QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this);1910 connect(pAnimation, SIGNAL(finished()), this, SLOT(sltSlidingComplete()), Qt::QueuedConnection);1911 1912 /* Left root animation: */1913 {1914 QPropertyAnimation *pLeftAnimation = new QPropertyAnimation(m_pLeftRoot, "geometry", this);1915 connect(pLeftAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltLeftRootSlidingProgress()));1916 QRectF startGeo = m_pLeftRoot->geometry();1917 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :1918 startGeo.translated(startGeo.width(), 0);1919 pLeftAnimation->setEasingCurve(QEasingCurve::InCubic);1920 pLeftAnimation->setDuration(500);1921 pLeftAnimation->setStartValue(startGeo);1922 pLeftAnimation->setEndValue(endGeo);1923 pAnimation->addAnimation(pLeftAnimation);1924 }1925 1926 /* Right root animation: */1927 {1928 QPropertyAnimation *pRightAnimation = new QPropertyAnimation(m_pRightRoot, "geometry", this);1929 connect(pRightAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltRightRootSlidingProgress()));1930 QRectF startGeo = m_pRightRoot->geometry();1931 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :1932 startGeo.translated(startGeo.width(), 0);1933 pRightAnimation->setEasingCurve(QEasingCurve::InCubic);1934 pRightAnimation->setDuration(500);1935 pRightAnimation->setStartValue(startGeo);1936 pRightAnimation->setEndValue(endGeo);1937 pAnimation->addAnimation(pRightAnimation);1938 }1939 1940 /* Start animation: */1941 pAnimation->start();1942 }1943 1944 QList<UIGChooserItem*> UIGChooserModel::gatherMachineItems(const QList<UIGChooserItem*> &selectedItems) const1945 {1946 QList<UIGChooserItem*> machineItems;1947 foreach (UIGChooserItem *pItem, selectedItems)1948 {1949 if (pItem->type() == UIGChooserItemType_Machine)1950 machineItems << pItem;1951 if (pItem->type() == UIGChooserItemType_Group)1952 machineItems << gatherMachineItems(pItem->items());1953 }1954 return machineItems;1955 }1956 1957 void UIGChooserModel::removeMachineItems(const QStringList &names, QList<UIGChooserItem*> &selectedItems)1958 {1959 /* Show machine items remove dialog: */1960 int rc = msgCenter().confirmMachineItemRemoval(names);1961 if (rc == QIMessageBox::Cancel)1962 return;1963 1964 /* Remove all the required items: */1965 foreach (UIGChooserItem *pItem, selectedItems)1966 if (names.contains(pItem->name()))1967 delete pItem;1968 1969 /* And update model: */1970 updateGroupTree();1971 updateNavigation();1972 updateLayout();1973 if (mainRoot()->hasItems())1974 setCurrentItem(0);1975 else1976 unsetCurrentItem();1977 saveGroupSettings();1978 }1979 1980 void UIGChooserModel::unregisterMachines(const QStringList &ids)1981 {1982 /* Populate machine list: */1983 QList<CMachine> machines;1984 CVirtualBox vbox = vboxGlobal().virtualBox();1985 foreach (const QString &strId, ids)1986 {1987 CMachine machine = vbox.FindMachine(strId);1988 if (!machine.isNull())1989 machines << machine;1990 }1991 1992 /* Show machine remove dialog: */1993 int rc = msgCenter().confirmMachineDeletion(machines);1994 if (rc != QIMessageBox::Cancel)1995 {1996 /* For every selected item: */1997 foreach (CMachine machine, machines)1998 {1999 if (rc == QIMessageBox::Yes)2000 {2001 /* Unregister and cleanup machine's data & hard-disks: */2002 CMediumVector mediums = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);2003 if (machine.isOk())2004 {2005 /* Delete machine hard-disks: */2006 CProgress progress = machine.Delete(mediums);2007 if (machine.isOk())2008 {2009 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png", 0, true);2010 if (progress.GetResultCode() != 0)2011 msgCenter().cannotDeleteMachine(machine, progress);2012 }2013 }2014 if (!machine.isOk())2015 msgCenter().cannotDeleteMachine(machine);2016 }2017 else2018 {2019 /* Just unregister machine: */2020 machine.Unregister(KCleanupMode_DetachAllReturnNone);2021 if (!machine.isOk())2022 msgCenter().cannotDeleteMachine(machine);2023 }2024 }2025 }2026 }2027 2028 void UIGChooserModel::enumerateInaccessibleItems(const QList<UIGChooserItem*> &il, QList<UIGChooserItem*> &ol) const2029 {2030 /* Enumerate all the passed items: */2031 foreach (UIGChooserItem *pItem, il)2032 {2033 /* If item is inaccessible machine: */2034 if (pItem->type() == UIGChooserItemType_Machine)2035 {2036 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem())2037 if (!pMachineItem->accessible() && !contains(ol, pItem))2038 ol << pMachineItem;2039 }2040 /* If item is group: */2041 else if (pItem->type() == UIGChooserItemType_Group)2042 {2043 /* Enumerate all the machine items recursively: */2044 enumerateInaccessibleItems(pItem->items(UIGChooserItemType_Machine), ol);2045 /* Enumerate all the group items recursively: */2046 enumerateInaccessibleItems(pItem->items(UIGChooserItemType_Group), ol);2047 }2048 }2049 }2050 2051 bool UIGChooserModel::contains(const QList<UIGChooserItem*> &il, UIGChooserItem *pLookupItem) const2052 {2053 /* We assume passed list contains only machine items: */2054 foreach (UIGChooserItem *pItem, il)2055 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem())2056 if (pMachineItem->id() == pLookupItem->toMachineItem()->id())2057 return true;2058 return false;2059 }2060 2061 void UIGChooserModel::sortItems(UIGChooserItem *pParent, bool fRecursively /* = false */)2062 {2063 /* Sort group items: */2064 QMap<QString, UIGChooserItem*> sorter;2065 foreach (UIGChooserItem *pItem, pParent->items(UIGChooserItemType_Group))2066 {2067 sorter.insert(pItem->name().toLower(), pItem);2068 if (fRecursively)2069 sortItems(pItem, fRecursively);2070 }2071 pParent->setItems(sorter.values(), UIGChooserItemType_Group);2072 2073 /* Sort machine items: */2074 sorter.clear();2075 foreach (UIGChooserItem *pItem, pParent->items(UIGChooserItemType_Machine))2076 sorter.insert(pItem->name().toLower(), pItem);2077 pParent->setItems(sorter.values(), UIGChooserItemType_Machine);2078 2079 /* Update model: */2080 updateNavigation();2081 updateLayout();2082 }2083 2084 void UIGChooserModel::makeSureGroupDefinitionsSaveIsFinished()2085 {2086 /* Cleanup if necessary: */2087 if (UIGroupDefinitionSaveThread::instance())2088 UIGroupDefinitionSaveThread::cleanup();2089 }2090 2091 void UIGChooserModel::makeSureGroupOrdersSaveIsFinished()2092 {2093 /* Cleanup if necessary: */2094 if (UIGroupOrderSaveThread::instance())2095 UIGroupOrderSaveThread::cleanup();2096 }2097 2098 1783 UIGChooserItem* UIGChooserModel::lookForItem(UIGChooserItem *pParent, const QString &strStartingFrom) 2099 1784 { … … 2112 1797 /* Nothing found: */ 2113 1798 return 0; 1799 } 1800 1801 void UIGChooserModel::loadGroupTree() 1802 { 1803 /* Add all the machines we have into the group-tree: */ 1804 LogRel(("Loading VMs started...\n")); 1805 foreach (const CMachine &machine, vboxGlobal().virtualBox().GetMachines()) 1806 addMachineIntoTheTree(machine); 1807 LogRel(("Loading VMs finished.\n")); 1808 } 1809 1810 void UIGChooserModel::addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible /* = false */) 1811 { 1812 /* Which VM we are loading: */ 1813 if (machine.isNull()) 1814 LogRel((" ERROR: VM is NULL!\n")); 1815 else 1816 LogRel((" Loading VM {%s}...\n", machine.GetId().toAscii().constData())); 1817 /* Is that machine accessible? */ 1818 if (machine.GetAccessible()) 1819 { 1820 /* VM is accessible: */ 1821 QString strName = machine.GetName(); 1822 LogRel((" VM {%s} is accessible.\n", strName.toAscii().constData())); 1823 /* Which groups passed machine attached to? */ 1824 QVector<QString> groups = machine.GetGroups(); 1825 QStringList groupList = groups.toList(); 1826 QString strGroups = groupList.join(", "); 1827 LogRel((" VM {%s} groups are {%s}.\n", strName.toAscii().constData(), 1828 strGroups.toAscii().constData())); 1829 foreach (QString strGroup, groups) 1830 { 1831 /* Remove last '/' if any: */ 1832 if (strGroup.right(1) == "/") 1833 strGroup.truncate(strGroup.size() - 1); 1834 /* Create machine item with found group item as parent: */ 1835 LogRel((" Creating item for VM {%s}, group {%s}.\n", strName.toAscii().constData(), 1836 strGroup.toAscii().constData())); 1837 createMachineItem(machine, getGroupItem(strGroup, mainRoot(), fMakeItVisible)); 1838 } 1839 /* Update group definitions: */ 1840 m_groups[machine.GetId()] = groupList; 1841 } 1842 /* Inaccessible machine: */ 1843 else 1844 { 1845 /* VM is accessible: */ 1846 LogRel((" VM {%s} is inaccessible.\n", machine.GetId().toAscii().constData())); 1847 /* Create machine item with main-root group item as parent: */ 1848 createMachineItem(machine, mainRoot()); 1849 } 1850 } 1851 1852 UIGChooserItem* UIGChooserModel::getGroupItem(const QString &strName, UIGChooserItem *pParentItem, bool fAllGroupsOpened) 1853 { 1854 /* Check passed stuff: */ 1855 if (pParentItem->name() == strName) 1856 return pParentItem; 1857 1858 /* Prepare variables: */ 1859 QString strFirstSubName = strName.section('/', 0, 0); 1860 QString strFirstSuffix = strName.section('/', 1, -1); 1861 QString strSecondSubName = strFirstSuffix.section('/', 0, 0); 1862 QString strSecondSuffix = strFirstSuffix.section('/', 1, -1); 1863 1864 /* Passed group name equal to first sub-name: */ 1865 if (pParentItem->name() == strFirstSubName) 1866 { 1867 /* Make sure first-suffix is NOT empty: */ 1868 AssertMsg(!strFirstSuffix.isEmpty(), ("Invalid group name!")); 1869 /* Trying to get group item among our children: */ 1870 foreach (UIGChooserItem *pGroupItem, pParentItem->items(UIGChooserItemType_Group)) 1871 { 1872 if (pGroupItem->name() == strSecondSubName) 1873 { 1874 UIGChooserItem *pFoundItem = getGroupItem(strFirstSuffix, pGroupItem, fAllGroupsOpened); 1875 if (UIGChooserItemGroup *pFoundGroupItem = pFoundItem->toGroupItem()) 1876 if (fAllGroupsOpened && pFoundGroupItem->closed()) 1877 pFoundGroupItem->open(false); 1878 return pFoundItem; 1879 } 1880 } 1881 } 1882 1883 /* Found nothing? Creating: */ 1884 UIGChooserItemGroup *pNewGroupItem = 1885 new UIGChooserItemGroup(/* Parent item and desired group name: */ 1886 pParentItem, strSecondSubName, 1887 /* Should be new group opened when created? */ 1888 fAllGroupsOpened || shouldBeGroupOpened(pParentItem, strSecondSubName), 1889 /* Which position new group item should be placed in? */ 1890 getDesiredPosition(pParentItem, UIGChooserItemType_Group, strSecondSubName)); 1891 return strSecondSuffix.isEmpty() ? pNewGroupItem : getGroupItem(strFirstSuffix, pNewGroupItem, fAllGroupsOpened); 1892 } 1893 1894 bool UIGChooserModel::shouldBeGroupOpened(UIGChooserItem *pParentItem, const QString &strName) 1895 { 1896 /* Prepare extra-data key for the parent-item: */ 1897 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 1898 /* Read group definitions: */ 1899 QStringList definitions = vboxGlobal().virtualBox().GetExtraDataStringList(strExtraDataKey); 1900 /* Return 'false' if no definitions found: */ 1901 if (definitions.isEmpty()) 1902 return false; 1903 1904 /* Prepare required group definition reg-exp: */ 1905 QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName); 1906 QRegExp definitionRegExp(strDefinitionTemplate); 1907 /* For each the group definition: */ 1908 for (int i = 0; i < definitions.size(); ++i) 1909 { 1910 /* Get current definition: */ 1911 const QString &strDefinition = definitions[i]; 1912 /* Check if this is required definition: */ 1913 if (definitionRegExp.indexIn(strDefinition) == 0) 1914 { 1915 /* Get group descriptor: */ 1916 QString strDescriptor(definitionRegExp.cap(1)); 1917 if (strDescriptor.contains('o')) 1918 return true; 1919 } 1920 } 1921 1922 /* Return 'false' by default: */ 1923 return false; 1924 } 1925 1926 int UIGChooserModel::getDesiredPosition(UIGChooserItem *pParentItem, UIGChooserItemType type, const QString &strName) 1927 { 1928 /* End of list (by default)? */ 1929 int iNewItemDesiredPosition = -1; 1930 /* Which position should be new item placed by definitions: */ 1931 int iNewItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strName); 1932 /* If some position wanted: */ 1933 if (iNewItemDefinitionPosition != -1) 1934 { 1935 /* Start of list if some definition present: */ 1936 iNewItemDesiredPosition = 0; 1937 /* We have to check all the existing item positions: */ 1938 QList<UIGChooserItem*> items = pParentItem->items(type); 1939 for (int i = items.size() - 1; i >= 0; --i) 1940 { 1941 /* Get current item: */ 1942 UIGChooserItem *pItem = items[i]; 1943 /* Which position should be current item placed by definitions? */ 1944 QString strDefinitionName = pItem->type() == UIGChooserItemType_Group ? pItem->name() : 1945 pItem->type() == UIGChooserItemType_Machine ? pItem->toMachineItem()->id() : 1946 QString(); 1947 AssertMsg(!strDefinitionName.isEmpty(), ("Wrong definition name!")); 1948 int iItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strDefinitionName); 1949 /* If some position wanted: */ 1950 if (iItemDefinitionPosition != -1) 1951 { 1952 AssertMsg(iItemDefinitionPosition != iNewItemDefinitionPosition, ("Incorrect definitions!")); 1953 if (iItemDefinitionPosition < iNewItemDefinitionPosition) 1954 { 1955 iNewItemDesiredPosition = i + 1; 1956 break; 1957 } 1958 } 1959 } 1960 } 1961 /* Return desired item position: */ 1962 return iNewItemDesiredPosition; 1963 } 1964 1965 int UIGChooserModel::positionFromDefinitions(UIGChooserItem *pParentItem, UIGChooserItemType type, const QString &strName) 1966 { 1967 /* Prepare extra-data key for the parent-item: */ 1968 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 1969 /* Read group definitions: */ 1970 QStringList definitions = vboxGlobal().virtualBox().GetExtraDataStringList(strExtraDataKey); 1971 /* Return 'false' if no definitions found: */ 1972 if (definitions.isEmpty()) 1973 return -1; 1974 1975 /* Prepare definition reg-exp: */ 1976 QString strDefinitionTemplateShort; 1977 QString strDefinitionTemplateFull; 1978 switch (type) 1979 { 1980 case UIGChooserItemType_Group: 1981 strDefinitionTemplateShort = QString("^g(\\S)*="); 1982 strDefinitionTemplateFull = QString("^g(\\S)*=%1$").arg(strName); 1983 break; 1984 case UIGChooserItemType_Machine: 1985 strDefinitionTemplateShort = QString("^m="); 1986 strDefinitionTemplateFull = QString("^m=%1$").arg(strName); 1987 break; 1988 default: return -1; 1989 } 1990 QRegExp definitionRegExpShort(strDefinitionTemplateShort); 1991 QRegExp definitionRegExpFull(strDefinitionTemplateFull); 1992 1993 /* For each the definition: */ 1994 int iDefinitionIndex = -1; 1995 for (int i = 0; i < definitions.size(); ++i) 1996 { 1997 /* Get current definition: */ 1998 QString strDefinition = definitions[i]; 1999 /* Check if this definition is of required type: */ 2000 if (definitionRegExpShort.indexIn(strDefinition) == 0) 2001 { 2002 ++iDefinitionIndex; 2003 /* Check if this definition is exactly what we need: */ 2004 if (definitionRegExpFull.indexIn(strDefinition) == 0) 2005 return iDefinitionIndex; 2006 } 2007 } 2008 2009 /* Return result: */ 2010 return -1; 2011 } 2012 2013 void UIGChooserModel::createMachineItem(const CMachine &machine, UIGChooserItem *pParentItem) 2014 { 2015 /* Create corresponding item: */ 2016 new UIGChooserItemMachine(/* Parent item and corresponding machine: */ 2017 pParentItem, machine, 2018 /* Which position new group item should be placed in? */ 2019 getDesiredPosition(pParentItem, UIGChooserItemType_Machine, machine.GetId())); 2020 } 2021 2022 void UIGChooserModel::saveGroupDefinitions() 2023 { 2024 /* Make sure there is no group save activity: */ 2025 if (UIGroupDefinitionSaveThread::instance()) 2026 return; 2027 2028 /* Prepare full group map: */ 2029 QMap<QString, QStringList> groups; 2030 gatherGroupDefinitions(groups, mainRoot()); 2031 2032 /* Save information in other thread: */ 2033 UIGroupDefinitionSaveThread::prepare(); 2034 emit sigGroupSavingStateChanged(); 2035 connect(UIGroupDefinitionSaveThread::instance(), SIGNAL(sigReload(QString)), 2036 this, SLOT(sltReloadMachine(QString))); 2037 UIGroupDefinitionSaveThread::instance()->configure(this, m_groups, groups); 2038 UIGroupDefinitionSaveThread::instance()->start(); 2039 m_groups = groups; 2040 } 2041 2042 void UIGChooserModel::saveGroupOrders() 2043 { 2044 /* Make sure there is no group save activity: */ 2045 if (UIGroupOrderSaveThread::instance()) 2046 return; 2047 2048 /* Prepare full group map: */ 2049 QMap<QString, QStringList> groups; 2050 gatherGroupOrders(groups, mainRoot()); 2051 2052 /* Save information in other thread: */ 2053 UIGroupOrderSaveThread::prepare(); 2054 emit sigGroupSavingStateChanged(); 2055 UIGroupOrderSaveThread::instance()->configure(this, groups); 2056 UIGroupOrderSaveThread::instance()->start(); 2057 } 2058 2059 void UIGChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &groups, 2060 UIGChooserItem *pParentGroup) 2061 { 2062 /* Iterate over all the machine items: */ 2063 foreach (UIGChooserItem *pItem, pParentGroup->items(UIGChooserItemType_Machine)) 2064 if (UIGChooserItemMachine *pMachineItem = pItem->toMachineItem()) 2065 if (pMachineItem->accessible()) 2066 groups[pMachineItem->id()] << fullName(pParentGroup); 2067 /* Iterate over all the group items: */ 2068 foreach (UIGChooserItem *pItem, pParentGroup->items(UIGChooserItemType_Group)) 2069 gatherGroupDefinitions(groups, pItem); 2070 } 2071 2072 void UIGChooserModel::gatherGroupOrders(QMap<QString, QStringList> &groups, 2073 UIGChooserItem *pParentItem) 2074 { 2075 /* Prepare extra-data key for current group: */ 2076 QString strExtraDataKey = UIDefs::GUI_GroupDefinitions + fullName(pParentItem); 2077 /* Iterate over all the group items: */ 2078 foreach (UIGChooserItem *pItem, pParentItem->items(UIGChooserItemType_Group)) 2079 { 2080 QString strGroupDescriptor(pItem->toGroupItem()->opened() ? "go" : "gc"); 2081 groups[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name()); 2082 gatherGroupOrders(groups, pItem); 2083 } 2084 /* Iterate over all the machine items: */ 2085 foreach (UIGChooserItem *pItem, pParentItem->items(UIGChooserItemType_Machine)) 2086 groups[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id()); 2087 } 2088 2089 QString UIGChooserModel::fullName(UIGChooserItem *pItem) 2090 { 2091 /* Return '/' for root-group: */ 2092 if (!pItem->parentItem()) 2093 return QString("/"); 2094 /* Get full parent name, append with '/' if not yet appended: */ 2095 QString strParentFullName = fullName(pItem->parentItem()); 2096 if (!strParentFullName.endsWith("/")) 2097 strParentFullName += QString("/"); 2098 /* Return full item name based on parent prefix: */ 2099 return strParentFullName + pItem->name(); 2100 } 2101 2102 2103 void UIGChooserModel::makeSureGroupDefinitionsSaveIsFinished() 2104 { 2105 /* Cleanup if necessary: */ 2106 if (UIGroupDefinitionSaveThread::instance()) 2107 UIGroupDefinitionSaveThread::cleanup(); 2108 } 2109 2110 void UIGChooserModel::makeSureGroupOrdersSaveIsFinished() 2111 { 2112 /* Cleanup if necessary: */ 2113 if (UIGroupOrderSaveThread::instance()) 2114 UIGroupOrderSaveThread::cleanup(); 2114 2115 } 2115 2116 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserModel.h
r43514 r43528 42 42 class QAction; 43 43 class QGraphicsSceneContextMenuEvent; 44 class CMachine; 44 class QTimer; 45 class QPaintDevice; 45 46 class UIVMItem; 46 47 class UIGChooserHandlerMouse; 47 48 class UIGChooserHandlerKeyboard; 48 class QTimer; 49 class QPaintDevice; 49 class CMachine; 50 50 51 51 /* Context-menu type: */ … … 63 63 signals: 64 64 65 /* Notifier: Root-item resize stuff: */ 65 /* Notifiers: Status-bar stuff: */ 66 void sigShowStatusMessage(const QString &strStatusMessage); 67 void sigClearStatusMessage(); 68 69 /* Notifier: Current-item stuff: */ 70 void sigSelectionChanged(); 71 72 /* Notifier: Focus-item stuff: */ 73 void sigFocusChanged(UIGChooserItem *pFocusItem); 74 75 /* Notifiers: Root-item stuff: */ 66 76 void sigRootItemResized(const QSizeF &size, int iMinimumWidth); 67 68 /* Notifier: Focus change: */69 void sigFocusChanged(UIGChooserItem *pFocusItem);70 71 /* Notifier: Selection change: */72 void sigSelectionChanged();73 74 /* Notifiers Status-bar stuff: */75 void sigClearStatusMessage();76 void sigShowStatusMessage(const QString &strStatusMessage);77 78 /* Notifier: Sliding start: */79 77 void sigSlidingStarted(); 80 78 81 /* Notifiers: Togglestuff: */79 /* Notifiers: Group-item stuff: */ 82 80 void sigToggleStarted(); 83 81 void sigToggleFinished(); 84 82 85 /* Notifiers: Group 83 /* Notifiers: Group-saving stuff: */ 86 84 void sigStartGroupSaving(); 87 85 void sigGroupSavingStateChanged(); … … 97 95 void cleanup(); 98 96 99 /* API: Scene getter: */97 /* API: Scene stuff: */ 100 98 QGraphicsScene* scene() const; 101 102 /* API: Paint-device getter: */103 99 QPaintDevice* paintDevice() const; 104 105 /* API: Root stuff: */ 100 QGraphicsItem* itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const; 101 102 /* API: Layout stuff: */ 103 void updateLayout(); 104 105 /* API: Navigation stuff: */ 106 const QList<UIGChooserItem*>& navigationList() const; 107 void removeFromNavigationList(UIGChooserItem *pItem); 108 void clearNavigationList(); 109 void updateNavigation(); 110 111 /* API: Current-item stuff: */ 112 UIVMItem* currentItem() const; 113 QString currentItemDefinition() const; 114 QList<UIVMItem*> currentItems() const; 115 const QList<UIGChooserItem*>& selectionList() const; 116 void setCurrentItem(int iItemIndex); 117 void setCurrentItem(UIGChooserItem *pItem); 118 void setCurrentItemDefinition(const QString &strDefinition); 119 void unsetCurrentItem(); 120 void addToSelectionList(UIGChooserItem *pItem); 121 void removeFromSelectionList(UIGChooserItem *pItem); 122 void clearSelectionList(); 123 void notifySelectionChanged(); 124 void activate(); 125 bool isSingleGroupSelected() const; 126 bool isAllItemsOfOneGroupSelected() const; 127 128 /* API: Focus-item stuff: */ 129 UIGChooserItem* focusItem() const; 130 void setFocusItem(UIGChooserItem *pItem, bool fWithSelection = false); 131 132 /* API: Root-item stuff: */ 106 133 UIGChooserItem* mainRoot() const; 107 134 UIGChooserItem* root() const; … … 110 137 bool isSlidingInProgress() const; 111 138 112 /* API: Current item stuff: */ 113 void setCurrentItem(int iItemIndex); 114 void setCurrentItem(UIGChooserItem *pItem); 115 void unsetCurrentItem(); 116 UIVMItem* currentItem() const; 117 QList<UIVMItem*> currentItems() const; 118 void setCurrentItemDefinition(const QString &strDefinition); 119 QString currentItemDefinition() const; 120 bool isSingleGroupSelected() const; 121 bool isAllItemsOfOneGroupSelected() const; 122 123 /* API: Focus item stuff: */ 124 void setFocusItem(UIGChooserItem *pItem, bool fWithSelection = false); 125 UIGChooserItem* focusItem() const; 126 127 /* API: Positioning item stuff: */ 128 QGraphicsItem* itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const; 129 130 /* API: Update stuff: */ 139 /* API: Group-item stuff: */ 140 QString uniqueGroupName(UIGChooserItem *pRoot); 141 void startEditing(); 131 142 void updateGroupTree(); 132 143 133 /* API: Navigation stuff: */ 134 const QList<UIGChooserItem*>& navigationList() const; 135 void removeFromNavigationList(UIGChooserItem *pItem); 136 void clearNavigationList(); 137 void updateNavigation(); 138 139 /* API: Selection stuff: */ 140 const QList<UIGChooserItem*>& selectionList() const; 141 void addToSelectionList(UIGChooserItem *pItem); 142 void removeFromSelectionList(UIGChooserItem *pItem); 143 void clearSelectionList(); 144 void notifySelectionChanged(); 145 146 /* API: Layout stuff: */ 147 void updateLayout(); 148 149 /* API: Editing stuff: */ 150 void startEditing(); 151 152 /* API: Drag and drop stuff: */ 144 /* API: Drag&drop stuff: */ 153 145 void setCurrentDragObject(QDrag *pDragObject); 154 146 155 /* API: Activate stuff: */ 156 void activate(); 157 158 /* API: Group name stuff: */ 159 QString uniqueGroupName(UIGChooserItem *pRoot); 160 161 /* API: Group saving stuff: */ 147 /* API: Item lookup stuff: */ 148 void lookFor(const QString &strLookupSymbol); 149 bool isPerformingLookup() const; 150 151 /* API: Saving stuff: */ 162 152 void saveGroupSettings(); 163 153 bool isGroupSavingInProgress() const; 164 165 /* API: Lookup stuff: */166 void lookFor(const QString &strLookupSymbol);167 bool isPerformingLookup() const;168 154 169 155 private slots: … … 176 162 void sltSnapshotChanged(QString strId, QString strSnapshotId); 177 163 178 /* Handler: View-resize: */164 /* Handler: Chooser-view stuff: */ 179 165 void sltHandleViewResized(); 180 166 181 /* Handler: Drag object destruction: */ 182 void sltCurrentDragObjectDestroyed(); 183 void sltStartScrolling(); 184 185 /* Handlers: Remove currently selected items: */ 186 void sltRemoveCurrentlySelectedGroup(); 187 void sltRemoveCurrentlySelectedMachine(); 188 189 /* Handler: Group add stuff: */ 190 void sltAddGroupBasedOnChosenItems(); 191 192 /* Handler: Group name editing stuff: */ 193 void sltStartEditingSelectedGroup(); 194 195 /* Handler: Create new machine stuff: */ 196 void sltCreateNewMachine(); 197 198 /* Handler: Context menu hovering: */ 199 void sltActionHovered(QAction *pAction); 200 201 /* Handler: Focus item destruction: */ 167 /* Handler: Focus-item stuff: */ 202 168 void sltFocusItemDestroyed(); 203 169 204 /* Handlers: Root- slidingstuff: */170 /* Handlers: Root-item stuff: */ 205 171 void sltLeftRootSlidingProgress(); 206 172 void sltRightRootSlidingProgress(); 207 173 void sltSlidingComplete(); 208 174 209 /* Handler: Refresh stuff: */ 175 /* Handlers: Group-item stuff: */ 176 void sltAddGroupBasedOnChosenItems(); 177 void sltStartEditingSelectedGroup(); 178 void sltSortGroup(); 179 void sltRemoveCurrentlySelectedGroup(); 180 181 /* Handlers: Machine-item stuff: */ 182 void sltCreateNewMachine(); 183 void sltReloadMachine(const QString &strId); 184 void sltSortParentGroup(); 210 185 void sltPerformRefreshAction(); 211 212 /* Handlers: Sorting stuff: */ 213 void sltSortParentGroup(); 214 void sltSortGroup(); 215 216 /* Handlers: Group saving stuff: */ 186 void sltRemoveCurrentlySelectedMachine(); 187 188 /* Handlers: Drag&drop stuff: */ 189 void sltStartScrolling(); 190 void sltCurrentDragObjectDestroyed(); 191 192 /* Handler: Context-menu stuff: */ 193 void sltActionHovered(QAction *pAction); 194 195 /* Handler: Item lookup stuff: */ 196 void sltEraseLookupTimer(); 197 198 /* Handlers: Saving stuff: */ 217 199 void sltGroupSavingStart(); 218 200 void sltGroupDefinitionsSaveComplete(); 219 201 void sltGroupOrdersSaveComplete(); 220 void sltReloadMachine(const QString &strId);221 222 /* Handler: Lookup stuff: */223 void sltEraseLookupTimer();224 202 225 203 private: … … 253 231 void cleanupScene(); 254 232 255 /* Event handler: */233 /* Handler: Event-filter: */ 256 234 bool eventFilter(QObject *pWatched, QEvent *pEvent); 257 235 258 /* Helper s: Focus itemstuff: */259 void clearRealFocus();260 261 /* Helpers: Current 236 /* Helper: Navigation stuff: */ 237 QList<UIGChooserItem*> createNavigationList(UIGChooserItem *pItem); 238 239 /* Helpers: Current-item stuff: */ 262 240 UIVMItem* searchCurrentItem(const QList<UIGChooserItem*> &list) const; 263 241 void enumerateCurrentItems(const QList<UIGChooserItem*> &il, QList<UIVMItem*> &ol) const; 264 242 bool contains(const QList<UIVMItem*> &list, UIVMItem *pItem) const; 265 243 266 /* Helpers: Loading: */ 244 /* Helper: Focus-item stuff: */ 245 void clearRealFocus(); 246 247 /* Helper: Root-item stuff: */ 248 void slideRoot(bool fForward); 249 250 /* Helper: Group-item stuff: */ 251 UIGChooserItem* findGroupItem(const QString &strName, UIGChooserItem *pParent); 252 void updateGroupTree(UIGChooserItem *pGroupItem); 253 254 /* Helpers: Machine-item stuff: */ 255 UIGChooserItem* findMachineItem(const QString &strName, UIGChooserItem *pParent); 256 QList<UIGChooserItem*> gatherMachineItems(const QList<UIGChooserItem*> &selectedItems) const; 257 void enumerateInaccessibleItems(const QList<UIGChooserItem*> &il, QList<UIGChooserItem*> &ol) const; 258 bool contains(const QList<UIGChooserItem*> &il, UIGChooserItem *pLookupItem) const; 259 void sortItems(UIGChooserItem *pParent, bool fRecursively = false); 260 void updateMachineItems(const QString &strId, UIGChooserItem *pParent); 261 void removeMachineItems(const QString &strId, UIGChooserItem *pParent); 262 void removeMachineItems(const QStringList &names, QList<UIGChooserItem*> &selectedItems); 263 void unregisterMachines(const QStringList &ids); 264 265 /* Helpers: Context-menu stuff: */ 266 bool processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent); 267 void popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point); 268 269 /* Handler: Drag&drop event: */ 270 bool processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent); 271 272 /* Helper: Lookup stuff: */ 273 UIGChooserItem* lookForItem(UIGChooserItem *pParent, const QString &strStartingFrom); 274 275 /* Helpers: Loading stuff: */ 267 276 void loadGroupTree(); 268 277 void addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible = false); … … 273 282 void createMachineItem(const CMachine &machine, UIGChooserItem *pParentItem); 274 283 275 /* Helpers: Group saving stuff: */284 /* Helpers: Saving stuff: */ 276 285 void saveGroupDefinitions(); 277 286 void saveGroupOrders(); … … 279 288 void gatherGroupOrders(QMap<QString, QStringList> &groups, UIGChooserItem *pParentItem); 280 289 QString fullName(UIGChooserItem *pItem); 281 282 /* Helpers: Update stuff: */283 void updateGroupTree(UIGChooserItem *pGroupItem);284 285 /* Helpers: Navigation stuff: */286 QList<UIGChooserItem*> createNavigationList(UIGChooserItem *pItem);287 288 /* Helpers: Search stuff: */289 UIGChooserItem* findGroupItem(const QString &strName, UIGChooserItem *pParent);290 UIGChooserItem* findMachineItem(const QString &strName, UIGChooserItem *pParent);291 292 /* Helpers: Global event stuff: */293 void updateMachineItems(const QString &strId, UIGChooserItem *pParent);294 void removeMachineItems(const QString &strId, UIGChooserItem *pParent);295 296 /* Helpers: Context menu stuff: */297 bool processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent);298 void popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point);299 300 /* Handlers: Scroll event: */301 bool processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent);302 303 /* Helper: Root item stuff: */304 void slideRoot(bool fForward);305 306 /* Helper: Search stuff: */307 QList<UIGChooserItem*> gatherMachineItems(const QList<UIGChooserItem*> &selectedItems) const;308 309 /* Helpers: Remove stuff: */310 void removeMachineItems(const QStringList &names, QList<UIGChooserItem*> &selectedItems);311 void unregisterMachines(const QStringList &ids);312 313 /* Helper: Refresh stuff: */314 void enumerateInaccessibleItems(const QList<UIGChooserItem*> &il, QList<UIGChooserItem*> &ol) const;315 bool contains(const QList<UIGChooserItem*> &il, UIGChooserItem *pLookupItem) const;316 317 /* Helper: Sorting stuff: */318 void sortItems(UIGChooserItem *pParent, bool fRecursively = false);319 320 /* Helpers: Group saving stuff: */321 290 void makeSureGroupDefinitionsSaveIsFinished(); 322 291 void makeSureGroupOrdersSaveIsFinished(); 323 324 /* Helper: Lookup stuff: */325 UIGChooserItem* lookForItem(UIGChooserItem *pParent, const QString &strStartingFrom);326 292 327 293 /* Variables: */
Note:
See TracChangeset
for help on using the changeset viewer.