static int isBalanced(int op) { long ndata = NDATA; long nvars = NVARS; long i, j, k, ncells, length; int balanced = 1; long term[MAXVARS]; double **cts = (double **) 0; WHERE("isBalanced"); TRASH(NTRASH,errorExit); switch (op) { case ONEWAYBALANCE: /* check if it is possible main effects are balanced*/ ncells = 0; for (i = 0; i < nvars; i++) { length = NCLASSES[i]; if (ndata % length != 0) { /* This one-way marginal table not possibly balanced */ return (0); } ncells = (length > ncells) ? length : ncells; } /*for (i = 0; i < nvars; i++)*/ /* Check that one-way marginals are balanced */ if(!getScratch(cts,GCTS,ncells,double)) { goto errorExit; } /* check all one-way marginals for balance */ for (i = 0; i < nvars; i++) { for(k = 0; k < nvars; k++) { term[k] = 0; } term[i] = 1; cellstat(Y, term, (double **) 0, (double **) 0,cts, CELLCOUNTS); balanced = cellsEqual(*cts, NCLASSES[i]); if (!balanced) { break; } } /*for (i = 0; i < nvars; i++)*/ break; case TWOWAYBALANCE: /* Check if all two-way marginal tables balanced */ ncells = 0; for (i = 1; i < nvars; i++) { for ( j = 0; j < i; j++) { length = NCLASSES[i] * NCLASSES[j]; if (ndata % length != 0) { /* This two-way marginal table not possibly balanced */ return (0); } ncells = (length > ncells) ? length : ncells; } } /*for (i = 1; i < nvars; i++)*/ if(!getScratch(cts,GCTS,ncells,double)) { goto errorExit; } /* check all two-way marginals for balance */ for (i = 1; i < nvars; i++) { for ( j = 0; j < i; j++) { for(k = 0; k < nvars; k++) { term[k] = 0; } term[i] = term[j] = 1; cellstat(Y, term, (double **) 0, (double **) 0,cts, CELLCOUNTS); balanced = cellsEqual(*cts, NCLASSES[i]*NCLASSES[j]); if (!balanced) { break; } } /*for ( j = 0; j < i; j++)*/ if (!balanced) { break; } } /*for (i = 1; i < nvars; i++)*/ break; case COMPLETEBALANCE: /* check for complete balance with all variables */ ncells = 1; for(i=0;i<nvars;i++) { term[i] = 1; ncells *= NCLASSES[i]; } if (ndata < ncells || ndata % ncells != 0) { /* complete balance not possible */ return (0); } if(!getScratch(cts,GCTS,ncells,double)) { goto errorExit; } /* compute cell counts */ cellstat(Y, term, (double **) 0, (double **) 0, cts, CELLCOUNTS); balanced = cellsEqual(*cts, ncells); break; } /*switch (op)*/ discardScratch(cts,GCTS,double); return (balanced); errorExit: emptyTrash(); if(MODELTYPE & ANOVA) { sprintf(OUTSTR, "Try anova(,unbalanced:T)"); } else { sprintf(OUTSTR, "Try poisson()"); } putOUTSTR(); return (-1); } /*isBalanced()*/
long getmodel(Symbolhandle list, long nargs, long startKey, long silent, Symbolhandle symhWts, Symbolhandle symhOffset, Symbolhandle symhN) { long i, j, i2, inc; long ny, ndata, nvars, nfactors, nterms, nerrorterms; long needed, balanced; long foundNonIntY = 0, foundNonIntN = 0; long intercept; long nmissing, nzerowt; long dim[2]; modelPointer kterm; Symbolhandle symh; double tmp; double *glmoffset, *casewts, *misswts, *ptmp, *factorvar; double yi, logitni, *y, *logitn, maxlevel; long caseweights = MODELTYPE & CASEWEIGHTS; char *ipfwarning = "WARNING: ipf() cannot be used, poisson() substituted"; modelInfoPointer info = (modelInfoPointer) 0; WHERE("getmodel"); TRASH(NTRASH,errorExit); *OUTSTR = '\0'; USEGLMOFFSET = 0; if (!initmodelparse(STRMODEL) || modelparse() != 0) {/* parse it */ goto errorExit; } info = getModelInfo(); /* retrieve model information */ if((ndata = checkVariables(info)) < 0) { goto errorExit; } if(!(GLMCONTROL & MULTIVAR) && !isVector(info->modelvars[0])) { sprintf(OUTSTR, "ERROR: non-vector response variable for %s()", FUNCNAME); goto errorExit; } NVARS = nvars = MODELINFO->nvars = info->nvars; NFACTORS = nfactors = MODELINFO->nfactors = info->nfactors; NTERMS = nterms = MODELINFO->nterms = info->nterms; NERRORTERMS = nerrorterms = MODELINFO->nerrorterms = info->nerrorterms; for(i=0;i<nerrorterms;i++) { modeltermAssign((modelPointer) info->errorterms[i], (modelPointer) MODELINFO->errorterms[i]); } /* Note: As of 930601, INTMODEL has been eliminated */ MODEL = info->model; info->model = (modelHandle) 0; if(MODELTYPE & (OLSREG|LEAPS)) { NFACTORS = nfactors = MODELINFO->nfactors = 0; intercept = 0; for(j=0;j<nterms;j++) { kterm = modelterm(MODEL,j); if(nvInTerm(kterm) > 1) { sprintf(OUTSTR, "ERROR: crossed variates and/or factors are illegal for %s()", FUNCNAME); goto errorExit; } /*if(nvInTerm(modelterm(MODEL,j)) > 1)*/ if(modeltermEqual(kterm,(modelPointer) NULLTERM)) { intercept = 1; } } /*for(j=0;j<nterms;j++)*/ } /*if(MODELTYPE & (OLSREG|LEAPS))*/ if (MODELTYPE & LEAPS && !intercept) { sprintf(OUTSTR, "ERROR: a model without an intercept is illegal for %s()", FUNCNAME); goto errorExit; } /* set up MODELVARS */ for (i = 0; i <= nvars; i++) { if(MODELVARS[i] != (Symbolhandle) 0) { Delete(MODELVARS[i]); } MODELVARS[i] = Makesymbol(REAL); if (MODELVARS[i] == (Symbolhandle) 0) { goto errorExit; } if (!Copy(info->modelvars[i], MODELVARS[i])) { goto errorExit; } info->modelvars[i] = (Symbolhandle) 0; strcpy(VARNAMES[i], NAME(MODELVARS[i])); if(i < nvars) { NCLASSES[i] = info->nclasses[i]; } clearNotes(MODELVARS[i]); } /*for (i = 0; i <= nvars; i++)*/ /* set up Y and X */ /* response and factors are known to be matrix or vector */ for (i = 0; i <= nvars; i++) { symh = MODELVARS[i]; (void) isMatrix(symh,dim); /* get dimensions */ if (HASLABELS(symh) && NDIMS(symh) != 2) { if (!fixupMatLabels(symh, USEBOTHLABELS)) { goto errorExit; } } /*if (HASLABELS(symh) && NDIMS(symh) != 2)*/ else { Setdims(symh, 2, dim); } if(i == 0) { Y = DATA(symh); ny = dim[1]; NDATA = (double) ndata; NY = (double) ny; /* make sure dimensions are correct, always 2 */ } /*if(i == 0)*/ else {/* i > 0 */ X[i - 1] = DATA(symh); if (isVariate(i-1)) { GLMCONTROL |= UNBALANCED; } /*if (isVariate(i-1))*/ } /*if(i == 0){}else{}*/ if(*OUTSTR) { goto errorExit; } } /*for (i = 0; i <= nvars; i++)*/ /* check for crossed variates */ for (i = 0; i < nvars-1; i++) { if (isVariate(i)) { /* variable i is a variate */ for (j = 0; j < nterms; j++) { /* find the terms it is in and check to see it is not crossed with another variate */ kterm = modelterm(MODEL,j); if(inTerm(i,kterm) && nvInTerm(kterm) > 1) { /* j-th term has variable i and there are at least 2 variables or factors in the term. Check to see if j-th term has another variate */ for (i2 = i+1; i2 < nvars; i2++) { if (isVariate(i2) && inTerm(i2,kterm)) { sprintf(OUTSTR, "ERROR: crossed variates in model are illegal for %s()", FUNCNAME); goto errorExit; } /*if (isVariate(i2) && inTerm(i2,kterm))*/ } /*for (i2 = 0; i2 < nvars; i2++)*/ } /*if(inTerm(i,kterm))*/ } /*for (j = 0; j < nterms; j++)*/ } /*if (isVariate(i))*/ } /*for (i = 0; i < nvars; i++)*/ /* check for case weights, i.e., user specified weights */ if (caseweights) { if (symhWts == (Symbolhandle) 0) { sprintf(OUTSTR, "ERROR: no weights given for %s()",FUNCNAME); } else if (TYPE(symhWts) != REAL || !isVector(symhWts) || symbolSize(symhWts) != ndata) { sprintf(OUTSTR, "ERROR: weights for %s() not REAL vector with length = nrows(%s)", FUNCNAME, NAME(MODELVARS[0])); } else { CASEWTS = (double **) mygethandle(ndata * sizeof(double)); if (CASEWTS == (double **) 0) { goto errorExit; } casewts = *CASEWTS; doubleCopy( DATAPTR(symhWts), casewts, ndata); for (i = 0; i < ndata; i++) { if (!isMissing(casewts[i]) && casewts[i] < 0) { sprintf(OUTSTR,"ERROR: negative case weights for %s()", FUNCNAME); break; } } /*for (i = 0; i < ndata; i++)*/ } if(*OUTSTR) { goto errorExit; } } /* if(caseweights) */ /* check for logistic N */ if (GLMCONTROL & BINOMDIST) { if (symhN == (Symbolhandle) 0) { sprintf(OUTSTR,"ERROR: no N variable given for %s()", FUNCNAME); } else if(!isVector(symhN) || TYPE(symhN) != REAL || symbolSize(symhN) != ndata && symbolSize(symhN) != 1) { sprintf(OUTSTR, "ERROR: %s() N not REAL scalar or vector of same length as response", FUNCNAME); } else { LOGITN = (double **) mygethandle(ndata * sizeof(double)); if (LOGITN == (double **) 0) { goto errorExit; } } if(*OUTSTR) { goto errorExit; } inc = (symbolSize(symhN) == 1) ? 0 : 1; i2 = 0; y = *Y; logitn = *LOGITN; ptmp = DATAPTR(symhN); for (i = 0; i < ndata; i++) { yi = y[i]; logitni = logitn[i] = ptmp[i2]; if (!isMissing(yi) && !isMissing(logitni)) { tmp = floor(logitni); if (tmp <= 0.0) { sprintf(OUTSTR, "ERROR: N values must be nonnegative for %s()", FUNCNAME); } else if (yi < 0.0 || yi > logitni) { sprintf(OUTSTR, "ERROR: response value out of range for %s()", FUNCNAME); } if(*OUTSTR) { goto errorExit; } if (!foundNonIntY && yi != floor(yi)) { foundNonIntY = 1; } if (!foundNonIntN && logitni != tmp) { foundNonIntN = 1; } } /*if (!isMissing(yi) && !isMissing(logitni))*/ i2 += inc; }/* for (i = 0; i < ndata; i++) */ } /*if (GLMCONTROL & BINOMDIST)*/ else if (GLMCONTROL & POISSONDIST) {/* check for nonnegative Y in Poisson distributed glm */ y = *Y; for (i = 0; i < ndata; i++) { yi = y[i]; if (!isMissing(yi)) { if (yi < 0.0) { sprintf(OUTSTR, "ERROR: response variable negative for %s()", FUNCNAME); goto errorExit; } if (!foundNonIntY && floor(yi) != yi) { foundNonIntY = 1; } } /*if (!isMissing(yi))*/ } /*for (i = 0; i < ndata; i++)*/ } /*if (glmcontrol & POISSONDIST)*/ if (!silent) { if (foundNonIntY) { sprintf(OUTSTR, "WARNING: non-integer value(s) of response variable for %s()", FUNCNAME); putErrorOUTSTR(); } if (foundNonIntN) { sprintf(OUTSTR, "WARNING: non-integer number N of trials for %s()", FUNCNAME); putErrorOUTSTR(); } } /*if (!silent)*/ /* check for user defined glmoffset */ if (symhOffset != (Symbolhandle) 0) { if (TYPE(symhOffset) != REAL || !isVector(symhOffset) || symbolSize(symhOffset) != ndata) { sprintf(OUTSTR, "ERROR: offsets for %s() not REAL vector nrows(offset) = nrows(response)", FUNCNAME); goto errorExit; } USEGLMOFFSET = 1; GLMOFFSET = (double **) mygethandle(ndata * sizeof(double)); if (GLMOFFSET == (double **) 0) { goto errorExit; } doubleCopy(DATAPTR(symhOffset), *GLMOFFSET, ndata); } /*if (symhOffset != (Symbolhandle) 0)*/ /* check for missing & fill MISSWTS if any are missing*/ nmissing = countMissing(MODELINFO, &MISSWTS); if(nmissing < 0) { goto errorExit; } if(caseweights || GLMCONTROL & BINOMDIST || USEGLMOFFSET) { casewts = (caseweights) ? *CASEWTS : (double *) 0; logitn = (GLMCONTROL & BINOMDIST) ? *LOGITN : (double *) 0; glmoffset = (USEGLMOFFSET) ? *GLMOFFSET : (double *) 0; misswts = (nmissing > 0) ? *MISSWTS : (double *) 0; for (i = 0; i < ndata; i++) { if (caseweights && isMissing(casewts[i]) || (GLMCONTROL & BINOMDIST) && isMissing(logitn[i]) || USEGLMOFFSET && isMissing(glmoffset[i])) { if(nmissing == 0) { MISSWTS = (double **) mygethandle(ndata * sizeof(double)); if (MISSWTS == (double **) 0) { goto errorExit; } misswts = *MISSWTS; doubleFill(misswts, 1.0, ndata); casewts = (caseweights) ? *CASEWTS : (double *) 0; logitn = (GLMCONTROL & BINOMDIST) ? *LOGITN : (double *) 0; glmoffset = (USEGLMOFFSET) ? *GLMOFFSET : (double *) 0; } /*if(nmissing == 0)*/ if (misswts[i] != 0.0) { misswts[i] = 0.0; nmissing++; } } } /*for (i = 0; i < ndata; i++)*/ } /*if(caseweights || GLMCONTROL & BINOMDIST || USEGLMOFFSET)*/ if(nmissing > 0) { MODELTYPE |= MISSWEIGHTS; GLMCONTROL |= UNBALANCED; misswts = *MISSWTS; } /*if(nmissing > 0)*/ /* find the actual maximum factor levels included */ if (nfactors > 0) { for (j = 0; j < nvars; j++) { if (!isVariate(j)) { factorvar = *(X[j]); maxlevel = 0; for (i = 0;i < ndata; i++) { if (!isMissing(factorvar[i]) && factorvar[i] > maxlevel && (nmissing == 0 || misswts[i] > 0.0)) { maxlevel = factorvar[i]; } } /*for (i = 0;i < ndata; i++)*/ NCLASSES[j] = (long) maxlevel; } /*if (!isVariate(j))*/ } /*for (j = 0; j < nvars; j++)*/ } /*if (nfactors > 0)*/ if (nmissing > 0 && !silent) { putOutErrorMsg("WARNING: cases with missing values deleted"); } /* check for zero case weights, i.e., user specified weights */ if (caseweights) { casewts = *CASEWTS; misswts = (MODELTYPE & MISSWEIGHTS) ? *MISSWTS : (double *) 0; nzerowt = 0; for (i = 0; i < ndata; i++) { if ((!(MODELTYPE & MISSWEIGHTS) || misswts[i] > 0.0) && casewts[i] == 0) { nzerowt++; } } if (nzerowt != 0 && !silent) { putOutErrorMsg("WARNING: cases with zero weight completely removed"); } nmissing += nzerowt; } /*if (caseweights)*/ NOTMISSING = NDATA - nmissing; if(NOTMISSING == 0) { sprintf(OUTSTR, "ERROR: no non-missing cases with non-zero weight"); goto errorExit; } /* Check for possible Latin Square or other balanced main effect design for which balanced computation is appropriate In the future, we need code to recognize fractional factorials, confounded factorials, etc */ balanced = (!(GLMCONTROL & UNBALANCED) && !(MODELTYPE & FASTANOVA) && isBalanced(ONEWAYBALANCE)); if (balanced && nvars > 1) { if (anovaEffectsOnly(1)) { balanced = isBalanced(TWOWAYBALANCE); } else { balanced = isBalanced(COMPLETEBALANCE); } if (balanced < 0) { goto errorExit; } } /*if (balanced)*/ if(!balanced) { GLMCONTROL |= UNBALANCED; if (MODELTYPE & IPF) { MODELTYPE &= ~IPF; MODELTYPE |= POISSONREG; if(!silent) { putOutErrorMsg(ipfwarning); } } } /*if(!balanced)*/ /* check for incremental deviances specified by extra argument */ if (MODELTYPE & (ITERGLMS | IPF) && !INCREMENTAL && nargs > startKey && !isKeyword(COMPVALUE(list,nargs-1))) { INCREMENTAL = 1; } /* 990319 moved creation of side-effect variables DEPVNAME and TERMNAMES to glm() */ /* save dependent variable name */ needed = strlen(VARNAME(0)) + 1; DEPVNAME = mygethandle(needed); if(DEPVNAME == (char **) 0) { goto errorExit; } /* re-dereference name after memory allocation */ strcpy(*DEPVNAME, VARNAME(0)); /* Create TERMNAMES */ needed = makeTermNames(0); /* get space requirement */ TERMNAMES = mygethandle(needed); if (TERMNAMES == (char **) 0) { goto errorExit; } /* now fill in TERMNAMES */ (void) makeTermNames(needed); emptyTrash(); return (0); /* normal (no error) return */ /* NOTE: cleanup of globals is done in glm after error return */ errorExit: putErrorOUTSTR(); emptyTrash(); if(info != (modelInfoPointer) 0) { mydisphandle((char **) info->model); MODEL = info->model = (modelHandle) 0; } return (1); } /*getmodel()*/
void BookmarksContentsWidget::showContextMenu(const QPoint &point) { const QModelIndex index = m_ui->bookmarksViewWidget->indexAt(point); const BookmarksModel::BookmarkType type = static_cast<BookmarksModel::BookmarkType>(index.data(BookmarksModel::TypeRole).toInt()); QMenu menu(this); if (type == BookmarksModel::TrashBookmark) { menu.addAction(Utils::getIcon(QLatin1String("trash-empty")), tr("Empty Trash"), BookmarksManager::getModel(), SLOT(emptyTrash()))->setEnabled(BookmarksManager::getModel()->getTrashItem()->rowCount() > 0); } else if (type == BookmarksModel::UnknownBookmark) { menu.addAction(Utils::getIcon(QLatin1String("inode-directory")), tr("Add Folder"), this, SLOT(addFolder())); menu.addAction(tr("Add Bookmark"), this, SLOT(addBookmark())); menu.addAction(tr("Add Separator"), this, SLOT(addSeparator())); } else { const bool isInTrash = BookmarksManager::getModel()->bookmarkFromIndex(index)->isInTrash(); menu.addAction(Utils::getIcon(QLatin1String("document-open")), tr("Open"), this, SLOT(openBookmark())); menu.addAction(tr("Open in New Tab"), this, SLOT(openBookmark()))->setData(WindowsManager::NewTabOpen); menu.addAction(tr("Open in New Background Tab"), this, SLOT(openBookmark()))->setData(static_cast<int>(WindowsManager::NewTabOpen | WindowsManager::BackgroundOpen)); menu.addSeparator(); menu.addAction(tr("Open in New Window"), this, SLOT(openBookmark()))->setData(WindowsManager::NewWindowOpen); menu.addAction(tr("Open in New Background Window"), this, SLOT(openBookmark()))->setData(static_cast<int>(WindowsManager::NewWindowOpen | WindowsManager::BackgroundOpen)); if (type == BookmarksModel::SeparatorBookmark || (type == BookmarksModel::FolderBookmark && index.child(0, 0).data(BookmarksModel::TypeRole).toInt() == 0)) { for (int i = 0; i < menu.actions().count(); ++i) { menu.actions().at(i)->setEnabled(false); } } if (type != BookmarksModel::RootBookmark) { Action *copyLinkAction = getAction(ActionsManager::CopyLinkToClipboardAction); copyLinkAction->setEnabled(type == BookmarksModel::UrlBookmark); menu.addSeparator(); menu.addAction(copyLinkAction); } if (!isInTrash) { menu.addSeparator(); QMenu *addMenu = menu.addMenu(tr("Add Bookmark")); addMenu->addAction(Utils::getIcon(QLatin1String("inode-directory")), tr("Add Folder"), this, SLOT(addFolder())); addMenu->addAction(tr("Add Bookmark"), this, SLOT(addBookmark())); addMenu->addAction(tr("Add Separator"), this, SLOT(addSeparator())); } if (type != BookmarksModel::RootBookmark) { menu.addSeparator(); if (isInTrash) { menu.addAction(tr("Restore Bookmark"), this, SLOT(restoreBookmark())); } else { menu.addAction(getAction(ActionsManager::DeleteAction)); } menu.addSeparator(); menu.addAction(tr("Properties…"), this, SLOT(bookmarkProperties())); } } menu.exec(m_ui->bookmarksViewWidget->mapToGlobal(point)); }
void NotesContentsWidget::showContextMenu(const QPoint &point) { const QModelIndex index(m_ui->notesViewWidget->indexAt(point)); const BookmarksModel::BookmarkType type(static_cast<BookmarksModel::BookmarkType>(index.data(BookmarksModel::TypeRole).toInt())); QMenu menu(this); if (type != BookmarksModel::UrlBookmark && type != BookmarksModel::TrashBookmark) { menu.addAction(getAction(ActionsManager::PasteAction)); menu.addSeparator(); } if (type == BookmarksModel::TrashBookmark) { menu.addAction(ThemesManager::getIcon(QLatin1String("trash-empty")), tr("Empty Trash"), NotesManager::getModel(), SLOT(emptyTrash()))->setEnabled(NotesManager::getModel()->getTrashItem()->rowCount() > 0); } else if (type == BookmarksModel::UnknownBookmark) { menu.addAction(ThemesManager::getIcon(QLatin1String("inode-directory")), tr("Add Folder"), this, SLOT(addFolder())); menu.addAction(tr("Add Bookmark"), this, SLOT(addNote())); menu.addAction(tr("Add Separator"), this, SLOT(addSeparator())); } else { const bool isInTrash(index.data(BookmarksModel::IsTrashedRole).toBool()); if (type == BookmarksModel::UrlBookmark) { menu.addAction(getAction(ActionsManager::CutAction)); menu.addAction(getAction(ActionsManager::CopyAction)); menu.addAction(getAction(ActionsManager::PasteAction)); menu.addSeparator(); } menu.addAction(ThemesManager::getIcon(QLatin1String("document-open")), tr("Open source page"), this, SLOT(openUrl()))->setEnabled(type == BookmarksModel::UrlBookmark && index.data(BookmarksModel::UrlRole).toUrl().isValid()); if (type != BookmarksModel::RootBookmark) { Action *copyLinkAction(getAction(ActionsManager::CopyLinkToClipboardAction)); copyLinkAction->setEnabled(type == BookmarksModel::UrlBookmark && index.data(BookmarksModel::UrlRole).toUrl().isValid()); menu.addAction(copyLinkAction); } if (!isInTrash) { menu.addSeparator(); QMenu *addMenu(menu.addMenu(tr("Add Note"))); addMenu->addAction(ThemesManager::getIcon(QLatin1String("inode-directory")), tr("Add Folder"), this, SLOT(addFolder())); addMenu->addAction(tr("Add Note"), this, SLOT(addNote())); addMenu->addAction(tr("Add Separator"), this, SLOT(addSeparator())); } if (type != BookmarksModel::RootBookmark) { menu.addSeparator(); if (isInTrash) { menu.addAction(tr("Restore Note"), this, SLOT(restoreNote())); } else { menu.addAction(getAction(ActionsManager::DeleteAction)); } } } menu.exec(m_ui->notesViewWidget->mapToGlobal(point)); }
void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) { PlacesItem* item = m_model->placesItem(index); if (!item) { return; } QMenu menu(this); QAction* emptyTrashAction = nullptr; QAction* editAction = nullptr; QAction* teardownAction = nullptr; QAction* ejectAction = nullptr; const QString label = item->text(); const bool isDevice = !item->udi().isEmpty(); const bool isTrash = (item->url().scheme() == QLatin1String("trash")); if (isDevice) { ejectAction = m_model->ejectAction(index); if (ejectAction) { ejectAction->setParent(&menu); menu.addAction(ejectAction); } teardownAction = m_model->teardownAction(index); if (teardownAction) { teardownAction->setParent(&menu); menu.addAction(teardownAction); } if (teardownAction || ejectAction) { menu.addSeparator(); } } else { if (isTrash) { emptyTrashAction = menu.addAction(QIcon::fromTheme(QStringLiteral("trash-empty")), i18nc("@action:inmenu", "Empty Trash")); emptyTrashAction->setEnabled(item->icon() == QLatin1String("user-trash-full")); menu.addSeparator(); } } QAction* openInNewWindowAction = menu.addAction(QIcon::fromTheme("window-new"), i18nc("@item:inmenu", "Open in New Window")); QAction* openInNewTabAction = menu.addAction(QIcon::fromTheme("tab-new"), i18nc("@item:inmenu", "Open in New Tab")); if (!isDevice && !isTrash) { menu.addSeparator(); } if (!isDevice) { editAction = menu.addAction(QIcon::fromTheme("document-properties"), i18nc("@item:inmenu", "Edit...")); } QAction* removeAction = nullptr; if (!isDevice && !item->isSystemItem()) { removeAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18nc("@item:inmenu", "Remove")); } QAction* hideAction = menu.addAction(i18nc("@item:inmenu", "Hide")); hideAction->setCheckable(true); hideAction->setChecked(item->isHidden()); buildGroupContextMenu(&menu, index); QAction* action = menu.exec(pos.toPoint()); if (action) { if (action == emptyTrashAction) { emptyTrash(); } else { // The index might have changed if devices were added/removed while // the context menu was open. index = m_model->index(item); if (index < 0) { // The item is not in the model any more, probably because it was an // external device that has been removed while the context menu was open. return; } if (action == editAction) { editEntry(index); } else if (action == removeAction) { m_model->deleteItem(index); } else if (action == hideAction) { item->setHidden(hideAction->isChecked()); } else if (action == openInNewWindowAction) { Dolphin::openNewWindow({KFilePlacesModel::convertedUrl(m_model->data(index).value("url").toUrl())}, this); } else if (action == openInNewTabAction) { // TriggerItem does set up the storage first and then it will // emit the slotItemMiddleClicked signal, because of Qt::MiddleButton. triggerItem(index, Qt::MiddleButton); } else if (action == teardownAction) { m_model->requestTearDown(index); } else if (action == ejectAction) { m_model->requestEject(index); } } } selectClosestItem(); }