19 #include <objc/objc-runtime.h>
20 #include <ApplicationServices/ApplicationServices.h>
21 #include <Security/Authorization.h>
22 #include <Security/AuthorizationTags.h>
30 qreal devicePixelRatio = qApp->primaryScreen()->devicePixelRatio();
31 QPixmap logo(QStringLiteral(
":/Icons/vuo.png"));
32 logo = logo.scaledToHeight(64 * devicePixelRatio, Qt::SmoothTransformation);
33 logo.setDevicePixelRatio(devicePixelRatio);
46 qreal dpr = QApplication::desktop()->devicePixelRatio();
47 QPixmap pixmap(pointsWide * dpr, pointsHigh * dpr);
48 pixmap.fill(Qt::transparent);
49 QPainter painter(&pixmap);
50 QIcon(svgPath).paint(&painter, 0, 0, pointsWide * dpr, pointsHigh * dpr);
53 QBuffer buffer(&bytes);
54 pixmap.save(&buffer,
"PNG");
55 return QString(
"<img src='data:image/png;base64,")
57 + QString(
"' width=%1 height=%2 />")
73 QDesktopServices::openUrl(QUrl::fromLocalFile(path));
75 QMessageBox::information(NULL, QObject::tr(
"Vuo User Library folder"), QObject::tr(
"Please create this folder if you'd like to install nodes for this user account:\n\n%1").arg(path));
89 AuthorizationRef auth = NULL;
90 if (AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess)
92 AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
93 AuthorizationRights rights = {1, &right};
95 const char *promptString = QObject::tr(
"Vuo wants to create its System Library folder.").toUtf8().constData();
96 AuthorizationItem prompt = {kAuthorizationEnvironmentPrompt, strlen(promptString), (
void *)promptString, 0};
97 AuthorizationEnvironment environment = {1, &prompt};
99 if (AuthorizationCopyRights(auth, &rights, &environment,
100 kAuthorizationFlagDefaults
101 | kAuthorizationFlagInteractionAllowed
102 | kAuthorizationFlagPreAuthorize
103 | kAuthorizationFlagExtendRights,
104 NULL) == errAuthorizationSuccess)
106 const char *args[] = {
"-p", strdup(path.toUtf8().data()), NULL };
108 #pragma clang diagnostic push
109 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
111 if (AuthorizationExecuteWithPrivileges(auth,
"/bin/mkdir", kAuthorizationFlagDefaults, (
char *
const *)args, &pipe) == errAuthorizationSuccess)
112 #pragma clang diagnostic pop
119 bytesRead = read(fileno(pipe), buffer,
sizeof(buffer));
123 free((
char *)args[1]);
126 AuthorizationFree(auth, kAuthorizationFlagDefaults);
131 QDesktopServices::openUrl(QUrl::fromLocalFile(path));
133 QMessageBox::information(NULL, QObject::tr(
"Vuo System Library folder"), QObject::tr(
"Please create this folder if you'd like to install nodes for all users on this computer:\n\n%1").arg(path));
148 bool optionKeyPressed = (CGEventSourceFlagsState(kCGEventSourceStateCombinedSessionState) & kCGEventFlagMaskAlternate);
150 bool optionKeyPressed = (
event->modifiers() & Qt::AltModifier);
153 return optionKeyPressed;
172 string dir, file, ext;
179 editLabel = QObject::tr((
"Edit " + sourceKind +
"…").c_str());
180 sourcePath = QString::fromStdString(expectedSourcePath);
198 map<QString, QString> successorForNodeClass;
199 successorForNodeClass[
"vuo.mesh.make.lines"] =
"vuo.scene.make.lines";
200 successorForNodeClass[
"vuo.mesh.make.lineStrips"] =
"vuo.scene.make.lineStrips";
201 successorForNodeClass[
"vuo.mesh.make.parametric"] =
"vuo.scene.make.parametric";
202 successorForNodeClass[
"vuo.mesh.make.points"] =
"vuo.scene.make.points";
203 successorForNodeClass[
"vuo.mesh.make.sphere"] =
"vuo.scene.make.sphere";
204 successorForNodeClass[
"vuo.mesh.make.square"] =
"vuo.scene.make.square";
205 successorForNodeClass[
"vuo.mesh.make.triangle"] =
"vuo.scene.make.triangle";
208 if (successorForNodeClass[oldNodeClass] == newNodeClass)
214 QString oldSuffix =
"";
215 QString newSuffix =
"";
216 int minLength = qMin(oldNodeClass.length(), newNodeClass.length());
217 for (
int i = 0; (i < minLength); ++i)
219 if (oldNodeClass.at(i) == newNodeClass.at(i))
220 root += oldNodeClass.at(i);
225 oldSuffix = oldNodeClass.right(oldNodeClass.length()-root.length());
226 newSuffix = newNodeClass.right(newNodeClass.length()-root.length());
228 bool oldSuffixIsNumeric =
false;
229 int oldSuffixVal = oldSuffix.toInt(&oldSuffixIsNumeric);
231 bool newSuffixIsNumeric =
false;
232 int newSuffixVal = newSuffix.toInt(&newSuffixIsNumeric);
234 if (newSuffixIsNumeric && (oldSuffix.isEmpty() || (oldSuffixIsNumeric && (newSuffixVal > oldSuffixVal))))
239 bool rootEndsInNumberSegment =
false;
240 for (
int i = root.length()-1; i >= 0; --i)
242 if (root.at(i).isDigit())
246 if (root.at(i) ==
'.')
247 rootEndsInNumberSegment =
true;
252 return !rootEndsInNumberSegment;
263 QList<QMainWindow *> openWindows;
264 for (QWidget *openWidget : QApplication::topLevelWidgets())
266 openWindows.append(
static_cast<QMainWindow *
>(openWidget));
268 std::sort(openWindows.begin(), openWindows.end(), [](
const QMainWindow *window1,
const QMainWindow *window2) {
269 return window1->windowTitle().remove(
"[*]").compare(window2->windowTitle().remove(
"[*]"), Qt::CaseInsensitive) < 0;
280 QList<VuoEditorWindow *> openCompositionWindows;
283 openCompositionWindows.append(
static_cast<VuoEditorWindow *
>(openWindow));
285 return openCompositionWindows;
295 std::sort(openWindows.begin(), openWindows.end(), [](
const QMainWindow *window1,
const QMainWindow *window2) {
296 id nsView1 = (id)window1->winId();
297 id nsWindow1 = objc_msgSend(nsView1, sel_getUid(
"window"));
298 long orderedIndex1 = (long)objc_msgSend(nsWindow1, sel_getUid(
"orderedIndex"));
300 id nsView2 = (id)window2->winId();
301 id nsWindow2 = objc_msgSend(nsView2, sel_getUid(
"window"));
302 long orderedIndex2 = (long)objc_msgSend(nsWindow2, sel_getUid(
"orderedIndex"));
304 return orderedIndex1 < orderedIndex2;
315 QString canonicalFilePath = QFileInfo(filename).canonicalFilePath();
318 if (openWindow->windowFilePath() == canonicalFilePath)
411 id nsView = (id)window->winId();
412 id nsWindow = objc_msgSend(nsView, sel_getUid(
"window"));
413 objc_msgSend(nsWindow, sel_getUid(
"setAlphaValue:"), opacity/255.);