mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Add Last Post Column in GroupTreeWidget.
Hidden by default. A context menu is added.
This commit is contained in:
parent
1352631807
commit
2ebacf36ed
@ -43,7 +43,8 @@
|
||||
#define COLUMN_NAME 0
|
||||
#define COLUMN_UNREAD 1
|
||||
#define COLUMN_POPULARITY 2
|
||||
#define COLUMN_COUNT 3
|
||||
#define COLUMN_LAST_POST 3
|
||||
#define COLUMN_COUNT 4
|
||||
#define COLUMN_DATA COLUMN_NAME
|
||||
|
||||
#define ROLE_ID Qt::UserRole
|
||||
@ -100,9 +101,12 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
|
||||
|
||||
/* Initialize tree widget */
|
||||
ui->treeWidget->setColumnCount(COLUMN_COUNT);
|
||||
ui->treeWidget->enableColumnCustomize(true);
|
||||
ui->treeWidget->setColumnCustomizable(COLUMN_NAME, false);
|
||||
|
||||
int S = QFontMetricsF(font()).height() ;
|
||||
int W = QFontMetricsF(font()).width("999") ;
|
||||
int D = QFontMetricsF(font()).width("9999-99-99[]") ;
|
||||
|
||||
/* Set header resize modes and initial section sizes */
|
||||
QHeaderView *header = ui->treeWidget->header ();
|
||||
@ -113,6 +117,15 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
|
||||
header->resizeSection(COLUMN_UNREAD, W+4) ;
|
||||
QHeaderView_setSectionResizeModeColumn(header, COLUMN_POPULARITY, QHeaderView::Fixed);
|
||||
header->resizeSection(COLUMN_POPULARITY, 2*S) ;
|
||||
QHeaderView_setSectionResizeModeColumn(header, COLUMN_LAST_POST, QHeaderView::Fixed);
|
||||
header->resizeSection(COLUMN_LAST_POST, D+4) ;
|
||||
header->setSectionHidden(COLUMN_LAST_POST, true);
|
||||
|
||||
QTreeWidgetItem *headerItem = ui->treeWidget->headerItem();
|
||||
headerItem->setText(COLUMN_NAME, tr("Name"));
|
||||
headerItem->setText(COLUMN_UNREAD, tr("Unread"));
|
||||
headerItem->setText(COLUMN_POPULARITY, tr("Popularity"));
|
||||
headerItem->setText(COLUMN_LAST_POST, tr("Last Post"));
|
||||
|
||||
/* add filter actions */
|
||||
ui->filterLineEdit->addFilter(QIcon(), tr("Title"), FILTER_NAME_INDEX , tr("Search Title"));
|
||||
@ -192,9 +205,10 @@ void GroupTreeWidget::addToolButton(QToolButton *toolButton)
|
||||
ui->titleBarFrame->layout()->addWidget(toolButton);
|
||||
}
|
||||
|
||||
void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
|
||||
// Load and save settings (group must be started from the caller)
|
||||
void GroupTreeWidget::processSettings(bool load)
|
||||
{
|
||||
if (settings == NULL) {
|
||||
if (Settings == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,16 +218,18 @@ void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
|
||||
const int SORTBY_POSTS = 4;
|
||||
const int SORTBY_UNREAD = 5;
|
||||
|
||||
ui->treeWidget->processSettings(load);
|
||||
|
||||
if (load) {
|
||||
// load settings
|
||||
// load Settings
|
||||
|
||||
// state of order
|
||||
bool ascSort = settings->value("GroupAscSort", true).toBool();
|
||||
bool ascSort = Settings->value("GroupAscSort", true).toBool();
|
||||
actionSortAscending->setChecked(ascSort);
|
||||
actionSortDescending->setChecked(!ascSort);
|
||||
|
||||
// state of sort
|
||||
int sortby = settings->value("GroupSortBy").toInt();
|
||||
int sortby = Settings->value("GroupSortBy").toInt();
|
||||
switch (sortby) {
|
||||
case SORTBY_NAME:
|
||||
if (actionSortByName) {
|
||||
@ -242,10 +258,10 @@ void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// save settings
|
||||
// save Settings
|
||||
|
||||
// state of order
|
||||
settings->setValue("GroupAscSort", !(actionSortDescending && actionSortDescending->isChecked())); //True by default
|
||||
Settings->setValue("GroupAscSort", !(actionSortDescending && actionSortDescending->isChecked())); //True by default
|
||||
|
||||
// state of sort
|
||||
int sortby = SORTBY_NAME;
|
||||
@ -260,7 +276,7 @@ void GroupTreeWidget::processSettings(RshareSettings *settings, bool load)
|
||||
} else if (actionSortByUnread && actionSortByUnread->isChecked()) {
|
||||
sortby = SORTBY_UNREAD;
|
||||
}
|
||||
settings->setValue("GroupSortBy", sortby);
|
||||
Settings->setValue("GroupSortBy", sortby);
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,6 +469,11 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
|
||||
/* Set last post */
|
||||
qlonglong lastPost = itemInfo.lastpost.toTime_t();
|
||||
item->setData(COLUMN_DATA, ROLE_LASTPOST, -lastPost); // negative for correct sorting
|
||||
if(itemInfo.lastpost == QDateTime::fromTime_t(0))
|
||||
item->setText(COLUMN_LAST_POST, tr("Never"));
|
||||
else
|
||||
item->setText(COLUMN_LAST_POST, itemInfo.lastpost.toString(Qt::ISODate).replace("T"," "));
|
||||
|
||||
|
||||
/* Set visible posts */
|
||||
item->setData(COLUMN_DATA, ROLE_POSTS, -itemInfo.max_visible_posts);// negative for correct sorting
|
||||
|
@ -77,8 +77,8 @@ public:
|
||||
// Add a tool button to the tool area
|
||||
void addToolButton(QToolButton *toolButton);
|
||||
|
||||
// Load and save settings (group must be startet from the caller)
|
||||
void processSettings(RshareSettings *settings, bool load);
|
||||
// Load and save settings (group must be started from the caller)
|
||||
void processSettings(bool load);
|
||||
|
||||
// Add a new category item
|
||||
QTreeWidgetItem *addCategoryItem(const QString &name, const QIcon &icon, bool expand);
|
||||
|
@ -194,7 +194,7 @@ void GxsGroupFrameDialog::processSettings(bool load)
|
||||
Settings->setValue("Splitter", ui->splitter->saveState());
|
||||
}
|
||||
|
||||
ui->groupTreeWidget->processSettings(Settings, load);
|
||||
ui->groupTreeWidget->processSettings(load);
|
||||
|
||||
Settings->endGroup();
|
||||
}
|
||||
@ -253,94 +253,100 @@ void GxsGroupFrameDialog::todo()
|
||||
|
||||
void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point)
|
||||
{
|
||||
QString id = ui->groupTreeWidget->itemIdAt(point);
|
||||
if (id.isEmpty()) return;
|
||||
|
||||
mGroupId = RsGxsGroupId(id.toStdString());
|
||||
int subscribeFlags = ui->groupTreeWidget->subscribeFlags(QString::fromStdString(mGroupId.toStdString()));
|
||||
|
||||
bool isAdmin = IS_GROUP_ADMIN(subscribeFlags);
|
||||
bool isPublisher = IS_GROUP_PUBLISHER(subscribeFlags);
|
||||
bool isSubscribed = IS_GROUP_SUBSCRIBED(subscribeFlags);
|
||||
|
||||
QMenu contextMnu(this);
|
||||
|
||||
QAction *action;
|
||||
QString id = ui->groupTreeWidget->itemIdAt(point);
|
||||
if (!id.isEmpty())
|
||||
{
|
||||
|
||||
if (mMessageWidget) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab()));
|
||||
if (mGroupId.isNull() || messageWidget(mGroupId, true)) {
|
||||
action->setEnabled(false);
|
||||
mGroupId = RsGxsGroupId(id.toStdString());
|
||||
int subscribeFlags = ui->groupTreeWidget->subscribeFlags(QString::fromStdString(mGroupId.toStdString()));
|
||||
|
||||
bool isAdmin = IS_GROUP_ADMIN(subscribeFlags);
|
||||
bool isPublisher = IS_GROUP_PUBLISHER(subscribeFlags);
|
||||
bool isSubscribed = IS_GROUP_SUBSCRIBED(subscribeFlags);
|
||||
|
||||
|
||||
QAction *action;
|
||||
|
||||
if (mMessageWidget) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_TABNEW), tr("Open in new tab"), this, SLOT(openInNewTab()));
|
||||
if (mGroupId.isNull() || messageWidget(mGroupId, true)) {
|
||||
action->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSubscribed) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe"), this, SLOT(unsubscribeGroup()));
|
||||
action->setEnabled (!mGroupId.isNull() && IS_GROUP_SUBSCRIBED(subscribeFlags));
|
||||
} else {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe"), this, SLOT(subscribeGroup()));
|
||||
action->setDisabled (mGroupId.isNull() || IS_GROUP_SUBSCRIBED(subscribeFlags));
|
||||
}
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
contextMnu.addAction(QIcon(icon(ICON_NEW)), text(TEXT_NEW), this, SLOT(newGroup()));
|
||||
|
||||
action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Details"), this, SLOT(showGroupDetails()));
|
||||
action->setEnabled (!mGroupId.isNull());
|
||||
|
||||
action = contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Details"), this, SLOT(editGroupDetails()));
|
||||
action->setEnabled (!mGroupId.isNull() && isAdmin);
|
||||
|
||||
uint32_t current_store_time = mInterface->getStoragePeriod(mGroupId)/86400 ;
|
||||
uint32_t current_sync_time = mInterface->getSyncPeriod(mGroupId)/86400 ;
|
||||
|
||||
std::cerr << "Got sync=" << current_sync_time << ". store=" << current_store_time << std::endl;
|
||||
QAction *actnn = NULL;
|
||||
|
||||
QMenu *ctxMenu2 = contextMnu.addMenu(tr("Synchronise posts of last...")) ;
|
||||
actnn = ctxMenu2->addAction(tr(" 5 days" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 5)) ; if(current_sync_time == 5) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 2 weeks" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 15)) ; if(current_sync_time == 15) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 month" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 30)) ; if(current_sync_time == 30) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 3 months" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 90)) ; if(current_sync_time == 90) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 6 months" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant(180)) ; if(current_sync_time ==180) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 year " ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant(372)) ; if(current_sync_time ==372) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" Indefinitly"),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 0)) ; if(current_sync_time == 0) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
|
||||
ctxMenu2 = contextMnu.addMenu(tr("Store posts for at most...")) ;
|
||||
actnn = ctxMenu2->addAction(tr(" 5 days" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 5)) ; if(current_store_time == 5) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 2 weeks" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 15)) ; if(current_store_time == 15) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 month" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 30)) ; if(current_store_time == 30) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 3 months" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 90)) ; if(current_store_time == 90) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 6 months" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant(180)) ; if(current_store_time ==180) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 year " ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant(372)) ; if(current_store_time ==372) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" Indefinitly"),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 0)) ; if(current_store_time == 0) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
|
||||
if (shareKeyType()) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_SHARE), tr("Share publish permissions"), this, SLOT(sharePublishKey()));
|
||||
action->setEnabled(!mGroupId.isNull() && isPublisher);
|
||||
}
|
||||
|
||||
if (getLinkType() != RetroShareLink::TYPE_UNKNOWN) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyGroupLink()));
|
||||
action->setEnabled(!mGroupId.isNull());
|
||||
}
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsRead()));
|
||||
action->setEnabled (!mGroupId.isNull() && isSubscribed);
|
||||
|
||||
action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnread()));
|
||||
action->setEnabled (!mGroupId.isNull() && isSubscribed);
|
||||
|
||||
/* Add special actions */
|
||||
QList<QAction*> actions;
|
||||
groupTreeCustomActions(mGroupId, subscribeFlags, actions);
|
||||
if (!actions.isEmpty()) {
|
||||
contextMnu.addSeparator();
|
||||
contextMnu.addActions(actions);
|
||||
}
|
||||
}
|
||||
|
||||
if (isSubscribed) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe"), this, SLOT(unsubscribeGroup()));
|
||||
action->setEnabled (!mGroupId.isNull() && IS_GROUP_SUBSCRIBED(subscribeFlags));
|
||||
} else {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe"), this, SLOT(subscribeGroup()));
|
||||
action->setDisabled (mGroupId.isNull() || IS_GROUP_SUBSCRIBED(subscribeFlags));
|
||||
}
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
contextMnu.addAction(QIcon(icon(ICON_NEW)), text(TEXT_NEW), this, SLOT(newGroup()));
|
||||
|
||||
action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Details"), this, SLOT(showGroupDetails()));
|
||||
action->setEnabled (!mGroupId.isNull());
|
||||
|
||||
action = contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Details"), this, SLOT(editGroupDetails()));
|
||||
action->setEnabled (!mGroupId.isNull() && isAdmin);
|
||||
|
||||
uint32_t current_store_time = mInterface->getStoragePeriod(mGroupId)/86400 ;
|
||||
uint32_t current_sync_time = mInterface->getSyncPeriod(mGroupId)/86400 ;
|
||||
|
||||
std::cerr << "Got sync=" << current_sync_time << ". store=" << current_store_time << std::endl;
|
||||
QAction *actnn = NULL;
|
||||
|
||||
QMenu *ctxMenu2 = contextMnu.addMenu(tr("Synchronise posts of last...")) ;
|
||||
actnn = ctxMenu2->addAction(tr(" 5 days" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 5)) ; if(current_sync_time == 5) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 2 weeks" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 15)) ; if(current_sync_time == 15) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 month" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 30)) ; if(current_sync_time == 30) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 3 months" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 90)) ; if(current_sync_time == 90) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 6 months" ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant(180)) ; if(current_sync_time ==180) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 year " ),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant(372)) ; if(current_sync_time ==372) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" Indefinitly"),this,SLOT(setSyncPostsDelay())) ; actnn->setData(QVariant( 0)) ; if(current_sync_time == 0) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
|
||||
ctxMenu2 = contextMnu.addMenu(tr("Store posts for at most...")) ;
|
||||
actnn = ctxMenu2->addAction(tr(" 5 days" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 5)) ; if(current_store_time == 5) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 2 weeks" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 15)) ; if(current_store_time == 15) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 month" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 30)) ; if(current_store_time == 30) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 3 months" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 90)) ; if(current_store_time == 90) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 6 months" ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant(180)) ; if(current_store_time ==180) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" 1 year " ),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant(372)) ; if(current_store_time ==372) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
actnn = ctxMenu2->addAction(tr(" Indefinitly"),this,SLOT(setStorePostsDelay())) ; actnn->setData(QVariant( 0)) ; if(current_store_time == 0) { actnn->setEnabled(false);actnn->setIcon(QIcon(":/images/start.png"));}
|
||||
|
||||
if (shareKeyType()) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_SHARE), tr("Share publish permissions"), this, SLOT(sharePublishKey()));
|
||||
action->setEnabled(!mGroupId.isNull() && isPublisher);
|
||||
}
|
||||
|
||||
if (getLinkType() != RetroShareLink::TYPE_UNKNOWN) {
|
||||
action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyGroupLink()));
|
||||
action->setEnabled(!mGroupId.isNull());
|
||||
}
|
||||
|
||||
contextMnu.addSeparator();
|
||||
|
||||
action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsRead()));
|
||||
action->setEnabled (!mGroupId.isNull() && isSubscribed);
|
||||
|
||||
action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnread()));
|
||||
action->setEnabled (!mGroupId.isNull() && isSubscribed);
|
||||
|
||||
/* Add special actions */
|
||||
QList<QAction*> actions;
|
||||
groupTreeCustomActions(mGroupId, subscribeFlags, actions);
|
||||
if (!actions.isEmpty()) {
|
||||
contextMnu.addSeparator();
|
||||
contextMnu.addActions(actions);
|
||||
}
|
||||
//Add Standard Menu
|
||||
ui->groupTreeWidget->treeWidget()->createStandardContextMenu(&contextMnu);
|
||||
|
||||
contextMnu.exec(QCursor::pos());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user