barrier/cmd/launcher/CScreensLinks.cpp

859 lines
20 KiB
C++
Raw Normal View History

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman, Nick Bolton, Sorin Sbarnea
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
2010-06-20 17:38:51 +00:00
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CConfig.h"
#include "ProtocolTypes.h"
#include "CStringUtil.h"
#include "CArch.h"
#include "CScreensLinks.h"
#include "CAddScreen.h"
#include "LaunchUtil.h"
#include "resource.h"
//
// CScreensLinks
//
CScreensLinks* CScreensLinks::s_singleton = NULL;
CScreensLinks::CScreensLinks(HWND parent, CConfig* config) :
m_parent(parent),
m_mainConfig(config),
m_config(&m_scratchConfig)
{
assert(s_singleton == NULL);
s_singleton = this;
// get formatting strings
m_linkFormat = getString(IDS_LINK_FORMAT);
m_intervalFormat = getString(IDS_LINK_INTERVAL_FORMAT);
m_newLinkLabel = getString(IDS_NEW_LINK);
m_sideLabel[kLeft - kFirstDirection] = getString(IDS_SIDE_LEFT);
m_sideLabel[kRight - kFirstDirection] = getString(IDS_SIDE_RIGHT);
m_sideLabel[kTop - kFirstDirection] = getString(IDS_SIDE_TOP);
m_sideLabel[kBottom - kFirstDirection] = getString(IDS_SIDE_BOTTOM);
// GDI objects
m_redPen = CreatePen(PS_INSIDEFRAME, 1, RGB(255, 0, 0));
}
CScreensLinks::~CScreensLinks()
{
DeleteObject(m_redPen);
s_singleton = NULL;
}
void
CScreensLinks::doModal()
{
// do dialog
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_SCREENS_LINKS),
m_parent, (DLGPROC)dlgProc, (LPARAM)this);
}
void
CScreensLinks::init(HWND hwnd)
{
// get initial config
m_scratchConfig = *m_mainConfig;
// fill side list box (in EDirection order)
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
SendMessage(child, CB_ADDSTRING, 0, (LPARAM)TEXT("---"));
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_LEFT).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_RIGHT).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_TOP).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_BOTTOM).c_str());
// create error boxes
m_srcSideError = createErrorBox(hwnd);
m_srcScreenError = createErrorBox(hwnd);
m_dstScreenError = createErrorBox(hwnd);
resizeErrorBoxes();
m_selectedLink = -1;
m_editedLink = CEdgeLink();
m_edgeLinks.clear();
updateScreens(hwnd, "");
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
bool
CScreensLinks::save(HWND /*hwnd*/)
{
*m_mainConfig = m_scratchConfig;
return true;
}
BOOL
CScreensLinks::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG:
init(hwnd);
return TRUE;
case WM_SIZE:
resizeErrorBoxes();
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
SetFocus(getItem(hwnd, IDOK));
if (save(hwnd)) {
EndDialog(hwnd, 0);
}
return TRUE;
case IDCANCEL:
EndDialog(hwnd, 0);
return TRUE;
case IDC_SCREENS_SCREENS:
switch (HIWORD(wParam)) {
case LBN_DBLCLK:
editScreen(hwnd);
return TRUE;
case LBN_SELCHANGE:
updateScreensControls(hwnd);
updateLinkView(hwnd);
return TRUE;
case LBN_SELCANCEL:
updateScreensControls(hwnd);
updateLinkView(hwnd);
return TRUE;
}
break;
case IDC_SCREENS_ADD_SCREEN:
addScreen(hwnd);
return TRUE;
case IDC_SCREENS_REMOVE_SCREEN:
removeScreen(hwnd);
return TRUE;
case IDC_SCREENS_EDIT_SCREEN:
editScreen(hwnd);
return TRUE;
case IDC_SCREENS_LINKS:
switch (HIWORD(wParam)) {
case LBN_SELCHANGE:
editLink(hwnd);
return TRUE;
case LBN_SELCANCEL:
editLink(hwnd);
return TRUE;
}
break;
case IDC_SCREENS_ADD_LINK:
addLink(hwnd);
return TRUE;
case IDC_SCREENS_REMOVE_LINK:
removeLink(hwnd);
return TRUE;
case IDC_SCREENS_SRC_SIDE:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeSrcSide(hwnd);
break;
}
break;
case IDC_SCREENS_SRC_SCREEN:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeSrcScreen(hwnd);
break;
}
break;
case IDC_SCREENS_DST_SCREEN:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeDstScreen(hwnd);
break;
}
break;
case IDC_SCREENS_SRC_START:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalStart(hwnd, LOWORD(wParam),
m_editedLink.m_srcInterval);
break;
}
break;
case IDC_SCREENS_SRC_END:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalEnd(hwnd, LOWORD(wParam),
m_editedLink.m_srcInterval);
break;
}
break;
case IDC_SCREENS_DST_START:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalStart(hwnd, LOWORD(wParam),
m_editedLink.m_dstInterval);
break;
}
break;
case IDC_SCREENS_DST_END:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalEnd(hwnd, LOWORD(wParam),
m_editedLink.m_dstInterval);
break;
}
break;
}
break;
case WM_CTLCOLORSTATIC:
switch (GetDlgCtrlID((HWND)lParam)) {
case IDC_SCREENS_OVERLAP_ERROR:
SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE));
SetTextColor((HDC)wParam, RGB(255, 0, 0));
return (BOOL)GetSysColorBrush(COLOR_3DFACE);
}
break;
// error outlines
case WM_DRAWITEM: {
DRAWITEMSTRUCT* di = (DRAWITEMSTRUCT*)lParam;
if (di->CtlType == ODT_STATIC) {
HGDIOBJ oldPen = SelectObject(di->hDC, m_redPen);
HGDIOBJ oldBrush = SelectObject(di->hDC,
GetStockObject(NULL_BRUSH));
Rectangle(di->hDC, di->rcItem.left, di->rcItem.top,
di->rcItem.right, di->rcItem.bottom);
SelectObject(di->hDC, oldPen);
SelectObject(di->hDC, oldBrush);
return TRUE;
}
break;
}
default:
break;
}
return FALSE;
}
BOOL CALLBACK
CScreensLinks::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
}
CString
CScreensLinks::getSelectedScreen(HWND hwnd) const
{
HWND child = getItem(hwnd, IDC_SCREENS_SCREENS);
LRESULT index = SendMessage(child, LB_GETCURSEL, 0, 0);
if (index == LB_ERR) {
return CString();
}
LRESULT size = SendMessage(child, LB_GETTEXTLEN, index, 0);
char* buffer = new char[size + 1];
SendMessage(child, LB_GETTEXT, index, (LPARAM)buffer);
buffer[size] = '\0';
CString result(buffer);
delete[] buffer;
return result;
}
void
CScreensLinks::addScreen(HWND hwnd)
{
CAddScreen dialog(hwnd, m_config, "");
if (dialog.doModal()) {
updateScreens(hwnd, dialog.getName());
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::editScreen(HWND hwnd)
{
CString oldName = getSelectedScreen(hwnd);
CAddScreen dialog(hwnd, m_config, oldName);
if (dialog.doModal()) {
CString newName = dialog.getName();
// rename screens in the edge list
if (newName != oldName) {
for (size_t i = 0; i < m_edgeLinks.size(); ++i) {
m_edgeLinks[i].rename(oldName, newName);
}
m_editedLink.rename(oldName, newName);
}
updateScreens(hwnd, newName);
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::removeScreen(HWND hwnd)
{
// remove screen from config (this also removes aliases)
m_config->removeScreen(getSelectedScreen(hwnd));
// update dialog
updateScreens(hwnd, "");
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
void
CScreensLinks::addLink(HWND hwnd)
{
if (m_editedLink.connect(m_config)) {
m_editedLink = CEdgeLink();
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::editLink(HWND hwnd)
{
// get selection
HWND child = getItem(hwnd, IDC_SCREENS_LINKS);
2009-10-21 16:25:08 +00:00
DWORD i = (DWORD)SendMessage(child, LB_GETCURSEL, 0, 0);
if (i != LB_ERR && i != (DWORD)m_edgeLinks.size()) {
// existing link
m_selectedLink = (SInt32)SendMessage(child, LB_GETITEMDATA, i, 0);
m_editedLink = m_edgeLinks[m_selectedLink];
}
else {
// new link
m_selectedLink = -1;
m_editedLink = CEdgeLink();
}
updateLinksControls(hwnd);
}
void
CScreensLinks::removeLink(HWND hwnd)
{
if (m_editedLink.disconnect(m_config)) {
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::updateScreens(HWND hwnd, const CString& selectName)
{
HWND child;
// set screen list
child = getItem(hwnd, IDC_SCREENS_SCREENS);
SendMessage(child, LB_RESETCONTENT, 0, 0);
for (CConfig::const_iterator index = m_config->begin();
index != m_config->end(); ) {
const CString& name = *index;
++index;
if (index != m_config->end()) {
SendMessage(child, LB_INSERTSTRING,
(WPARAM)-1, (LPARAM)name.c_str());
}
else {
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)name.c_str());
}
}
// find the named screen
if (!selectName.empty()) {
2009-10-21 16:25:08 +00:00
DWORD i = (DWORD)SendMessage(child, LB_FINDSTRINGEXACT,
(UINT)-1, (LPARAM)selectName.c_str());
if (i != LB_ERR) {
SendMessage(child, LB_SETSEL, TRUE, i);
}
}
}
void
CScreensLinks::updateScreensControls(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SCREENS);
bool screenSelected = (SendMessage(child, LB_GETCURSEL, 0, 0) != LB_ERR);
enableItem(hwnd, IDC_SCREENS_ADD_SCREEN, TRUE);
enableItem(hwnd, IDC_SCREENS_EDIT_SCREEN, screenSelected);
enableItem(hwnd, IDC_SCREENS_REMOVE_SCREEN, screenSelected);
}
void
CScreensLinks::updateLinks(HWND hwnd)
{
HWND links = getItem(hwnd, IDC_SCREENS_LINKS);
HWND srcScreens = getItem(hwnd, IDC_SCREENS_SRC_SCREEN);
HWND dstScreens = getItem(hwnd, IDC_SCREENS_DST_SCREEN);
// get old selection
CEdgeLink oldLink;
if (m_selectedLink != -1) {
oldLink = m_edgeLinks[m_selectedLink];
}
// clear links and screens
SendMessage(links, LB_RESETCONTENT, 0, 0);
SendMessage(srcScreens, CB_RESETCONTENT, 0, 0);
SendMessage(dstScreens, CB_RESETCONTENT, 0, 0);
m_edgeLinks.clear();
// add "no screen" items
SendMessage(srcScreens, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("----"));
SendMessage(dstScreens, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("----"));
// add links and screens
for (CConfig::const_iterator i = m_config->begin();
i != m_config->end(); ++i) {
const CString& name = *i;
// add screen
SendMessage(srcScreens, CB_INSERTSTRING, (WPARAM)-1,
(LPARAM)name.c_str());
SendMessage(dstScreens, CB_INSERTSTRING, (WPARAM)-1,
(LPARAM)name.c_str());
// add links for screen
for (CConfig::link_const_iterator j = m_config->beginNeighbor(name),
n = m_config->endNeighbor(name);
j != n; ++j) {
2009-10-21 16:25:08 +00:00
DWORD k = (DWORD)m_edgeLinks.size();
m_edgeLinks.push_back(CEdgeLink(name, *j));
SendMessage(links, LB_INSERTSTRING, (WPARAM)-1,
(LPARAM)formatLink(m_edgeLinks.back()).c_str());
SendMessage(links, LB_SETITEMDATA, (WPARAM)k, (LPARAM)k);
}
}
// add "new link" item to sort
SendMessage(links, LB_ADDSTRING, 0, (LPARAM)m_newLinkLabel.c_str());
// remove the "new link" item then insert it on the end
2009-10-21 16:25:08 +00:00
DWORD i = (DWORD)SendMessage(links, LB_FINDSTRINGEXACT,
(UINT)-1, (LPARAM)m_newLinkLabel.c_str());
if (i != LB_ERR) {
SendMessage(links, LB_DELETESTRING, i, 0);
}
SendMessage(links, LB_INSERTSTRING, (WPARAM)-1,
(LPARAM)getString(IDS_NEW_LINK).c_str());
SendMessage(links, LB_SETITEMDATA, (WPARAM)m_edgeLinks.size(),
(LPARAM)-1);
// select the same link as before
SendMessage(links, LB_SETCURSEL, (WPARAM)m_edgeLinks.size(), 0);
if (m_selectedLink != -1) {
m_selectedLink = -1;
2009-10-21 16:25:08 +00:00
for (SInt32 j = 0; j < (SInt32)m_edgeLinks.size(); ++j) {
if (m_edgeLinks[j] == oldLink) {
// found matching link
m_selectedLink = j;
2009-10-21 16:25:08 +00:00
for (UInt32 k = 0; k < (UInt32)m_edgeLinks.size(); ++k) {
if (SendMessage(links, LB_GETITEMDATA, k, 0) == (int)j) {
SendMessage(links, LB_SETCURSEL, k, 0);
break;
}
}
break;
}
}
// if we can't find the link anymore then reset edited link
if (m_selectedLink == -1) {
m_editedLink = CEdgeLink();
}
}
}
void
CScreensLinks::updateLinksControls(HWND hwnd)
{
// get selection. select "new link" if nothing is selected.
HWND child = getItem(hwnd, IDC_SCREENS_LINKS);
if (m_selectedLink == -1) {
SendMessage(child, LB_SETCURSEL, m_edgeLinks.size(), 0);
}
// enable/disable remove button
enableItem(hwnd, IDC_SCREENS_REMOVE_LINK, m_selectedLink != -1);
// fill link entry controls from m_editedLink
updateLinkEditControls(hwnd, m_editedLink);
updateLinkValid(hwnd, m_editedLink);
updateLinkView(hwnd);
}
void
CScreensLinks::changeSrcSide(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
m_editedLink.m_srcSide = (EDirection)SendMessage(child, CB_GETCURSEL, 0, 0);
updateLink(hwnd);
}
void
CScreensLinks::changeSrcScreen(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SCREEN);
m_editedLink.m_srcName = getWindowText(child);
updateLink(hwnd);
}
void
CScreensLinks::changeDstScreen(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_DST_SCREEN);
m_editedLink.m_dstName = getWindowText(child);
updateLink(hwnd);
}
void
CScreensLinks::changeIntervalStart(HWND hwnd, int id, CConfig::CInterval& i)
{
int x = (int)GetDlgItemInt(hwnd, id, NULL, FALSE);
if (x < 0) {
x = 0;
}
else if (x > 99) {
x = 99;
}
i.first = 0.01f * (float)x;
if (i.first >= i.second) {
i.second = 0.01f * (float)(x + 1);
}
updateLinkIntervalControls(hwnd, m_editedLink);
updateLink(hwnd);
}
void
CScreensLinks::changeIntervalEnd(HWND hwnd, int id, CConfig::CInterval& i)
{
int x = (int)GetDlgItemInt(hwnd, id, NULL, FALSE);
if (x < 1) {
x = 1;
}
else if (x > 100) {
x = 100;
}
i.second = 0.01f * (float)x;
if (i.first >= i.second) {
i.first = 0.01f * (float)(x - 1);
}
updateLinkIntervalControls(hwnd, m_editedLink);
updateLink(hwnd);
}
void
CScreensLinks::selectScreen(HWND hwnd, int id, const CString& name)
{
HWND child = getItem(hwnd, id);
2009-10-21 16:25:08 +00:00
DWORD i = (DWORD)SendMessage(child, CB_FINDSTRINGEXACT, (WPARAM)-1,
(LPARAM)name.c_str());
if (i == CB_ERR) {
// no match, select no screen
SendMessage(child, CB_SETCURSEL, 0, 0);
}
else {
SendMessage(child, CB_SETCURSEL, i, 0);
}
}
void
CScreensLinks::updateLinkEditControls(HWND hwnd, const CEdgeLink& link)
{
// fill link entry controls from link
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
SendMessage(child, CB_SETCURSEL, link.m_srcSide, 0);
selectScreen(hwnd, IDC_SCREENS_SRC_SCREEN, link.m_srcName);
selectScreen(hwnd, IDC_SCREENS_DST_SCREEN, link.m_dstName);
updateLinkIntervalControls(hwnd, link);
}
void
CScreensLinks::updateLinkIntervalControls(HWND hwnd, const CEdgeLink& link)
{
HWND child;
// src interval
child = getItem(hwnd, IDC_SCREENS_SRC_START);
setWindowText(child, formatIntervalValue(link.m_srcInterval.first));
child = getItem(hwnd, IDC_SCREENS_SRC_END);
setWindowText(child, formatIntervalValue(link.m_srcInterval.second));
// dst interval
child = getItem(hwnd, IDC_SCREENS_DST_START);
setWindowText(child, formatIntervalValue(link.m_dstInterval.first));
child = getItem(hwnd, IDC_SCREENS_DST_END);
setWindowText(child, formatIntervalValue(link.m_dstInterval.second));
}
void
CScreensLinks::updateLink(HWND hwnd)
{
updateLinkValid(hwnd, m_editedLink);
// update link in config
if (m_selectedLink != -1 && m_editedLinkIsValid) {
// editing an existing link and entry is valid
if (m_edgeLinks[m_selectedLink].disconnect(m_config)) {
// successfully removed old link
if (!m_editedLink.connect(m_config)) {
// couldn't set new link so restore old link
m_edgeLinks[m_selectedLink].connect(m_config);
}
else {
m_edgeLinks[m_selectedLink] = m_editedLink;
updateLinks(hwnd);
updateLinkEditControls(hwnd, m_editedLink);
}
}
}
updateLinkView(hwnd);
}
void
CScreensLinks::updateLinkValid(HWND hwnd, const CEdgeLink& link)
{
m_editedLinkIsValid = true;
// check source side and screen
if (link.m_srcSide == kNoDirection) {
m_editedLinkIsValid = false;
ShowWindow(m_srcSideError, SW_SHOWNA);
}
else {
ShowWindow(m_srcSideError, SW_HIDE);
}
if (!m_config->isCanonicalName(link.m_srcName)) {
m_editedLinkIsValid = false;
ShowWindow(m_srcScreenError, SW_SHOWNA);
}
else {
ShowWindow(m_srcScreenError, SW_HIDE);
}
// check for overlap. if editing a link we must remove it, then
// check for overlap and restore the old link.
bool overlap = false;
if (m_editedLinkIsValid) {
if (m_selectedLink == -1) {
if (link.overlaps(m_config)) {
m_editedLinkIsValid = false;
overlap = true;
}
}
else {
if (m_edgeLinks[m_selectedLink].disconnect(m_config)) {
overlap = link.overlaps(m_config);
m_edgeLinks[m_selectedLink].connect(m_config);
if (overlap) {
m_editedLinkIsValid = false;
}
}
}
}
ShowWindow(getItem(hwnd, IDC_SCREENS_OVERLAP_ERROR),
overlap ? SW_SHOWNA : SW_HIDE);
// check dst screen
if (!m_config->isCanonicalName(link.m_dstName)) {
m_editedLinkIsValid = false;
ShowWindow(m_dstScreenError, SW_SHOWNA);
}
else {
ShowWindow(m_dstScreenError, SW_HIDE);
}
// update add link button
enableItem(hwnd, IDC_SCREENS_ADD_LINK,
m_selectedLink == -1 && m_editedLinkIsValid);
}
void
CScreensLinks::updateLinkView(HWND /*hwnd*/)
{
// XXX -- draw visual of selected screen, highlighting selected link
}
HWND
CScreensLinks::createErrorBox(HWND parent)
{
return CreateWindow(TEXT("STATIC"), TEXT(""),
WS_CHILD | SS_OWNERDRAW,
0, 0, 1, 1,
parent, (HMENU)-1,
s_instance, NULL);
}
void
CScreensLinks::resizeErrorBoxes()
{
HWND hwnd = GetParent(m_srcSideError);
resizeErrorBox(m_srcSideError, getItem(hwnd, IDC_SCREENS_SRC_SIDE));
resizeErrorBox(m_srcScreenError, getItem(hwnd, IDC_SCREENS_SRC_SCREEN));
resizeErrorBox(m_dstScreenError, getItem(hwnd, IDC_SCREENS_DST_SCREEN));
}
void
CScreensLinks::resizeErrorBox(HWND box, HWND assoc)
{
RECT rect;
GetWindowRect(assoc, &rect);
MapWindowPoints(NULL, GetParent(box), (POINT*)&rect, 2);
SetWindowPos(box, HWND_TOP, rect.left - 1, rect.top - 1,
rect.right - rect.left + 2,
rect.bottom - rect.top + 2, SWP_NOACTIVATE);
}
CString
CScreensLinks::formatIntervalValue(float x) const
{
return CStringUtil::print("%d", (int)(x * 100.0f + 0.5f));
}
CString
CScreensLinks::formatInterval(const CConfig::CInterval& i) const
{
if (i.first == 0.0f && i.second == 1.0f) {
return "";
}
else {
CString start = formatIntervalValue(i.first);
CString end = formatIntervalValue(i.second);
return CStringUtil::format(m_intervalFormat.c_str(),
start.c_str(), end.c_str());
}
}
CString
CScreensLinks::formatLink(const CEdgeLink& link) const
{
CString srcInterval = formatInterval(link.m_srcInterval);
CString dstInterval = formatInterval(link.m_dstInterval);
return CStringUtil::format(m_linkFormat.c_str(),
link.m_srcName.c_str(), srcInterval.c_str(),
m_sideLabel[link.m_srcSide - kFirstDirection].c_str(),
link.m_dstName.c_str(), dstInterval.c_str());
}
//
// CScreensLinks::CEdgeLink
//
CScreensLinks::CEdgeLink::CEdgeLink() :
m_srcName(),
m_srcSide(kNoDirection),
m_srcInterval(0.0f, 1.0f),
m_dstName(),
m_dstInterval(0.0f, 1.0f)
{
// do nothing
}
CScreensLinks::CEdgeLink::CEdgeLink(const CString& name,
const CConfigLink& link) :
m_srcName(name),
m_srcSide(link.first.getSide()),
m_srcInterval(link.first.getInterval()),
m_dstName(link.second.getName()),
m_dstInterval(link.second.getInterval())
{
// do nothing
}
bool
CScreensLinks::CEdgeLink::connect(CConfig* config)
{
return config->connect(m_srcName, m_srcSide,
m_srcInterval.first, m_srcInterval.second,
m_dstName,
m_dstInterval.first, m_dstInterval.second);
}
bool
CScreensLinks::CEdgeLink::disconnect(CConfig* config)
{
return config->disconnect(m_srcName, m_srcSide, 0.5f *
(m_srcInterval.first + m_srcInterval.second));
}
void
CScreensLinks::CEdgeLink::rename(const CString& oldName, const CString& newName)
{
if (m_srcName == oldName) {
m_srcName = newName;
}
if (m_dstName == oldName) {
m_dstName = newName;
}
}
bool
CScreensLinks::CEdgeLink::overlaps(const CConfig* config) const
{
return config->hasNeighbor(m_srcName, m_srcSide,
m_srcInterval.first, m_srcInterval.second);
}
bool
CScreensLinks::CEdgeLink::operator==(const CEdgeLink& x) const
{
return (m_srcName == x.m_srcName &&
m_srcSide == x.m_srcSide &&
m_srcInterval == x.m_srcInterval &&
m_dstName == x.m_dstName &&
m_dstInterval == x.m_dstInterval);
}