//============================================================================= // // File : SetupWizard.cpp // Creation date : Sat Oct 6 02:06:53 2001 GMT by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program 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. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================== bool g_bFoundMirc; #include "SetupWizard.h" #include "KviApplication.h" #include "KviLocale.h" #include "KviFileUtils.h" #include "kvi_defaults.h" #include "KviMessageBox.h" #include "KviTalFileDialog.h" #include "KviQString.h" #include "KviEnvironment.h" #include "KviOptions.h" #include "KviConfigurationFile.h" #include "KviTalHBox.h" #include "KviRegExp.h" #include #include #include #include #include #include #include #include #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) #include // for MultiByteToWideChar #include // CoCreateInstance, CoInitialize & CO. #include // IShellLink IPersistFile & CO. #else #include // for symlink() #endif // libkvisetup.cpp extern QString g_szChoosenIncomingDirectory; extern int g_iThemeToApply; extern bool bNeedToApplyDefaults; extern unsigned int uPort; extern QString szHost; extern QString szUrl; extern QString szMircServers; extern QString szMircIni; #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) #define KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME "KVIrc4" #else #define KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME ".config/KVIrc" #endif SetupPage::SetupPage(SetupWizard * w) : QWidget(w) { QGridLayout * g = new QGridLayout(this); //setBackgroundColor(QColor(255,0,0)); // we need this to set localized text on buttons (see QT doc/ KviTalWizard class) w->KviTalWizard::backButton()->setText(__tr2qs("< &Back")); w->KviTalWizard::nextButton()->setText(__tr2qs("&Next >")); w->KviTalWizard::finishButton()->setText(__tr2qs("Finish")); w->KviTalWizard::cancelButton()->setText(__tr2qs("Cancel")); //w->KviTalWizard::helpButton()->setText(__tr2qs("Help")); m_pPixmapLabel = new QLabel(this); g->addWidget(m_pPixmapLabel, 0, 0); m_pPixmapLabel->setPixmap(*(w->m_pLabelPixmap)); m_pPixmapLabel->setFixedSize(w->m_pLabelPixmap->size()); m_pPixmapLabel->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); m_pPixmapLabel->setContentsMargins(0, 0, 0, 0); g->setSpacing(8); g->setContentsMargins(0, 0, 0, 0); m_pVBox = new KviTalVBox(this); m_pVBox->setSpacing(4); m_pVBox->setContentsMargins(0, 0, 0, 0); //m_pVBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding)); //m_pVBox->setBackgroundColor(QColor(0,80,0)); //m_pVBox->setMaximumHeight(450); g->addWidget(m_pVBox, 0, 1); g->setColumnStretch(1, 1); QLabel * l = new QLabel(m_pVBox); l->setAlignment(Qt::AlignLeft | Qt::AlignTop); QPalette pal = l->palette(); pal.setColor(l->backgroundRole(), QColor(48, 48, 48)); //aka #303030 pal.setColor(l->foregroundRole(), QColor(255, 255, 255)); //aka #FFFFFF l->setPalette(pal); l->setText("

 KVIrc " KVI_VERSION "

"); l->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); l->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); l->setAutoFillBackground(true); l->setContentsMargins(0, 0, 0, 0); m_pTextLabel = new QLabel(m_pVBox); m_pTextLabel->setWordWrap(true); m_pTextLabel->setAlignment(Qt::AlignJustify | Qt::AlignTop); m_pVBox->setStretchFactor(m_pTextLabel, 1); } SetupPage::~SetupPage() = default; SetupWizard::SetupWizard() : KviTalWizard(nullptr) { setWindowTitle(__tr2qs("Setup Wizard - KVIrc")); setWindowModality(Qt::NonModal); // non modal, otherwise the dialogs we show will not be usable g_bFoundMirc = false; QString szLabelText; QString szImagePath; g_pApp->getGlobalKvircDirectory(szImagePath, KviApplication::Pics, "kvi_setup_label.png"); // set name of the app desktop file; used by wayland to load the window icon QGuiApplication::setDesktopFileName("net.kvirc.KVIrc" KVIRC_VERSION_MAJOR); m_pLabelPixmap = new QPixmap(szImagePath); if(m_pLabelPixmap->isNull()) { delete m_pLabelPixmap; m_pLabelPixmap = new QPixmap(250, 450); } // // Welcome // m_pWelcome = new SetupPage(this); // here we go... QString szText = __tr2qs("

" "

Welcome :)

" "This is your first time running this version of KVIrc.
" "This wizard will guide you through the few steps " "required to complete the setup.

" "If you had a previous version of KVIrc installed, no worries. You will " "have a chance to preserve the old configuration." "

" "

Click \"Next\" to proceed.

"); m_pWelcome->m_pTextLabel->setText(szText); addPage(m_pWelcome, __tr2qs("Welcome to KVIrc")); setBackEnabled(m_pWelcome, false); setHelpEnabled(m_pWelcome, false); // // License // #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) //it have been already shown by installer SetupPage * m_pLicense = new SetupPage(this); m_pLicense->m_pTextLabel->setText(__tr2qs( "

All of the files in this distribution are covered by the GPL. " "In human terms this can be read as follows:
" "

    " "
  • KVIrc is free, use it, have fun! :)
  • " "
  • If you use any part of KVIrc in your own project, you must release that project under the same license.
  • " "

" "

The \"legalese\" version of the license is shown in the box below.

")); QTextEdit * ed = new QTextEdit(m_pLicense->m_pVBox); ed->setReadOnly(true); ed->setWordWrapMode(QTextOption::NoWrap); QString szLicense; QString szLicensePath; g_pApp->getGlobalKvircDirectory(szLicensePath, KviApplication::License, "ABOUT-LICENSE"); if(!KviFileUtils::loadFile(szLicensePath, szLicense)) { szLicense = __tr("Oops! Can't find the license file.\n" "It MUST be included in the distribution...\n" "Please report to "); } ed->setText(szLicense); m_pLicense->m_pVBox->setStretchFactor(ed, 1); addPage(m_pLicense, __tr2qs("Dreaded License Agreement")); setHelpEnabled(m_pLicense, false); #else m_pLicense = nullptr; #endif // // Directories // m_pDirectory = new SetupPage(this); m_pDirectory->m_pTextLabel->setText(__tr2qs("

Please choose a folder for " "KVIrc to store its settings and other data, and another for downloaded files. " "Make sure that you have permission to write to both folders.

" "The suggested locations are fine in most cases. If you don't know what " "this is about, just click \"Next\".

" "If you had a previous version of KVIrc installed, you can choose " "the existing directory for the settings, and your configuration " "will be preserved." "

")); QString tmp; m_pDirButtonGroup = new KviTalGroupBox(Qt::Horizontal, __tr2qs("Store configuration in folder"), m_pDirectory->m_pVBox); m_pDirUsePrev = new QRadioButton(__tr2qs("Use settings folder from previous installation"), m_pDirButtonGroup); connect(m_pDirUsePrev, SIGNAL(clicked()), this, SLOT(oldDirClicked())); m_pOldPathBox = new KviTalHBox(m_pDirButtonGroup); m_pOldDataPathEdit = new QLineEdit(m_pOldPathBox); connect(m_pOldDataPathEdit, SIGNAL(textChanged(const QString &)), this, SLOT(oldDataTextChanged(const QString &))); QPushButton * pb = new QPushButton(__tr2qs("&Browse..."), m_pOldPathBox); connect(pb, SIGNAL(clicked()), this, SLOT(chooseOldDataPath())); m_pOldPathBox->setSpacing(3); m_pOldPathBox->setStretchFactor(m_pOldDataPathEdit, 1); m_pDirUseNew = new QRadioButton(__tr2qs("Use new settings folder"), m_pDirButtonGroup); connect(m_pDirUseNew, SIGNAL(clicked()), this, SLOT(newDirClicked())); QLabel * l = new QLabel(m_pDirButtonGroup); l->setText(__tr2qs("Settings folder:")); m_pNewPathBox = new KviTalHBox(m_pDirButtonGroup); m_pDataPathEdit = new QLineEdit(m_pNewPathBox); pb = new QPushButton(__tr2qs("&Browse..."), m_pNewPathBox); connect(pb, SIGNAL(clicked()), this, SLOT(chooseDataPath())); m_pNewPathBox->setSpacing(3); m_pNewPathBox->setStretchFactor(m_pDataPathEdit, 1); #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) tmp = QTextCodec::codecForLocale()->toUnicode(getenv("APPDATA")); if(tmp.isEmpty()) tmp = QDir::homePath(); #else tmp = QDir::homePath(); #endif //COMPILE_ON_WINDOWS KviQString::ensureLastCharIs(tmp, KVI_PATH_SEPARATOR_CHAR); tmp.append(KVI_LOCAL_KVIRC_SUBDIRECTORY_NAME); KviFileUtils::adjustFilePath(tmp); m_pDataPathEdit->setText(tmp); l = new QLabel(m_pDirButtonGroup); l->setText(__tr2qs("Download files to folder:")); m_pNewIncomingBox = new KviTalHBox(m_pDirButtonGroup); m_pIncomingPathEdit = new QLineEdit(m_pNewIncomingBox); pb = new QPushButton(__tr2qs("&Browse..."), m_pNewIncomingBox); connect(pb, SIGNAL(clicked()), this, SLOT(chooseIncomingPath())); m_pNewIncomingBox->setSpacing(3); m_pNewIncomingBox->setStretchFactor(m_pIncomingPathEdit, 1); tmp = QDir::homePath(); KviQString::ensureLastCharIs(tmp, KVI_PATH_SEPARATOR_CHAR); tmp.append(KVI_DEFAULT_INCOMING_SUBDIRECTORY_NAME); KviFileUtils::adjustFilePath(tmp); m_pIncomingPathEdit->setText(tmp); m_pDirUseNew->toggle(); #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) m_pDirMakePortable = new QRadioButton(__tr2qs("All settings in shared program folder (portable)"), m_pDirButtonGroup); connect(m_pDirMakePortable, SIGNAL(clicked()), this, SLOT(portableClicked())); #endif // Pragma: Unused, takes only space. //m_pDirRestore = new QRadioButton(__tr2qs("Restore from backup archive"),m_pDirButtonGroup); //m_pDirRestore->setEnabled(false); //l = new QLabel(m_pDirectory->m_pVBox," "); //m_pDirectory->m_pVBox->setStretchFactor(m_pDirectory->m_pTextLabel,1); addPage(m_pDirectory, __tr2qs("Application Folders")); setHelpEnabled(m_pDirectory, false); connect(m_pDataPathEdit, SIGNAL(textChanged(const QString &)), this, SLOT(newDataTextChanged(const QString &))); connect(m_pIncomingPathEdit, SIGNAL(textChanged(const QString &)), this, SLOT(newIncomingTextChanged(const QString &))); // // Identity // m_pIdentity = new SetupPage(this); m_pIdentity->m_pTextLabel->setText(__tr2qs("Please choose a nickname.

" "Your nickname is the name that other IRC users will know you by. " "It can't contain spaces or punctuation. Some IRC networks will shorten your nickname if it is more than 32 characters " "long.

" "If in doubt, just enter the first nick that comes to mind. " "You will be able to change it later in the Identity properties, or with the /NICK command.")); KviTalGroupBox * gbox = new KviTalGroupBox(Qt::Horizontal, QString(), m_pIdentity->m_pVBox); m_pNickSelector = new KviStringSelector(gbox, __tr2qs("Nickname:"), &(KVI_OPTION_STRING(KviOption_stringNickname1)), true); m_pNickSelector->setMinimumLabelWidth(120); m_pNickSelector->setContentsMargins(0, 0, 0, 0); QObject::connect(m_pNickSelector->lineEdit(), SIGNAL(textChanged(const QString &)), this, SLOT(nickSelectorTextChanged(const QString &))); QValidator * v = new QRegularExpressionValidator(KviRegExp("[^-0-9 ][^ ]*"), gbox); m_pNickSelector->setValidator(v); QString szOptionalCtcpUserInfo = __tr2qs("This field is optional and will appear as part of the CTCP USERINFO reply."); QString szTrailing = "

" + szOptionalCtcpUserInfo; gbox = new KviTalGroupBox(Qt::Horizontal, __tr2qs("Profile"), m_pIdentity->m_pVBox); m_pRealNameSelector = new KviStringSelector(gbox, __tr2qs("Real name:"), &(KVI_OPTION_STRING(KviOption_stringRealname)), true); m_pRealNameSelector->setMinimumLabelWidth(120); m_pRealNameSelector->setContentsMargins(0, 0, 0, 0); KviTalHBox * hb = new KviTalHBox(gbox); hb->setSpacing(4); hb->setContentsMargins(0, 0, 0, 0); l = new QLabel(__tr2qs("Age:"), hb); l->setMinimumWidth(120); m_pAgeCombo = new QComboBox(hb); m_pAgeCombo->insertItem(0, __tr2qs("Unspecified")); unsigned int i; for(i = 1; i < 120; i++) { QString tmp; tmp.setNum(i); m_pAgeCombo->insertItem(m_pAgeCombo->count(), tmp); } bool bOk; i = KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge).toUInt(&bOk); if(!bOk) i = 0; if(i > 120) i = 120; m_pAgeCombo->setCurrentIndex(i); hb->setStretchFactor(m_pAgeCombo, 1); hb = new KviTalHBox(gbox); hb->setSpacing(4); hb->setContentsMargins(0, 0, 0, 0); l = new QLabel(__tr2qs("Gender:"), hb); l->setMinimumWidth(120); m_pGenderCombo = new QComboBox(hb); m_pGenderCombo->insertItem(0, __tr2qs("Unspecified")); m_pGenderCombo->insertItem(1, __tr2qs("Female")); m_pGenderCombo->insertItem(2, __tr2qs("Male")); if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender), "Male")) m_pGenderCombo->setCurrentIndex(2); else if(KviQString::equalCI(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender), "Female")) m_pGenderCombo->setCurrentIndex(1); else m_pGenderCombo->setCurrentIndex(0); hb->setStretchFactor(m_pGenderCombo, 1); m_pLocationSelector = new KviStringSelector(gbox, __tr2qs("Location:"), &(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoLocation)), true); m_pLocationSelector->setMinimumLabelWidth(120); m_pLocationSelector->setContentsMargins(0, 0, 0, 0); m_pLanguagesSelector = new KviStringSelector(gbox, __tr2qs("Languages:"), &(KVI_OPTION_STRING(KviOption_stringCtcpUserInfoLanguages)), true); m_pLanguagesSelector->setMinimumLabelWidth(120); m_pLanguagesSelector->setContentsMargins(0, 0, 0, 0); addPage(m_pIdentity, __tr2qs("Identity")); setHelpEnabled(m_pIdentity, false); // // Default theme // m_pTheme = new SetupPage(this); m_pTheme->m_pTextLabel->setText(__tr2qs( "

Here you can choose the default appearance of KVIrc.

" "The Fancy theme uses icons, a transparent background and a lot of colors. " "The Minimalist theme is designed for low-color displays " "or for \"console\" extremists; it's more or less white text on a black background.

" "If you had a previous version of KVIrc installed, you can choose to not apply any theme " "in order to preserve your current visual settings.

" "If you don't know what to choose, just use the default.

")); m_pThemeButtonGroup = new QGroupBox(m_pTheme->m_pVBox); QGridLayout * pThemeGrid = new QGridLayout(m_pThemeButtonGroup); m_pThemeButtonGroup->setLayout(pThemeGrid); QString szThemeImagePath; g_pApp->getGlobalKvircDirectory(szThemeImagePath, KviApplication::Pics, "kvi_setup_theme_hires.png"); QPixmap * pHiResPixmap = new QPixmap(szThemeImagePath); if(pHiResPixmap->isNull()) { delete pHiResPixmap; pHiResPixmap = new QPixmap(200, 118); } QLabel * pPixmapLabelHiRes = new QLabel(m_pThemeButtonGroup); pPixmapLabelHiRes->setPixmap(*pHiResPixmap); pPixmapLabelHiRes->setFixedSize(pHiResPixmap->size()); pPixmapLabelHiRes->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); pPixmapLabelHiRes->setContentsMargins(0, 0, 0, 0); pThemeGrid->addWidget(pPixmapLabelHiRes, 1, 1); m_pThemeHiRes = new QRadioButton(__tr2qs("&Fancy Theme"), m_pThemeButtonGroup); pThemeGrid->addWidget(m_pThemeHiRes, 2, 1); g_pApp->getGlobalKvircDirectory(szThemeImagePath, KviApplication::Pics, "kvi_setup_theme_lowres.png"); QPixmap * pLowResPixmap = new QPixmap(szThemeImagePath); if(pLowResPixmap->isNull()) { delete pLowResPixmap; pLowResPixmap = new QPixmap(250, 200); } QLabel * pPixmapLabelLowRes = new QLabel(m_pThemeButtonGroup); pPixmapLabelLowRes->setPixmap(*pLowResPixmap); pPixmapLabelLowRes->setFixedSize(pLowResPixmap->size()); pPixmapLabelLowRes->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); pPixmapLabelLowRes->setContentsMargins(0, 0, 0, 0); pThemeGrid->addWidget(pPixmapLabelLowRes, 1, 2); m_pThemeLoRes = new QRadioButton(__tr2qs("&Minimalist Theme"), m_pThemeButtonGroup); pThemeGrid->addWidget(m_pThemeLoRes, 2, 2); m_pThemeNone = new QRadioButton(__tr2qs("&Don't apply any theme"), m_pThemeButtonGroup); pThemeGrid->addWidget(m_pThemeNone, 3, 1); m_pThemeHiRes->setChecked(true); addPage(m_pTheme, __tr2qs("Default Theme")); setHelpEnabled(m_pTheme, false); // // Desktop integration // m_pDesktopIntegration = new SetupPage(this); szText = __tr2qs( "

" "Here you can choose how much KVIrc will integrate with " "your system." "

" "The default settings are fine for most users so if " "you're in doubt just click \"Finish\" to continue." "

"); m_pDesktopIntegration->m_pTextLabel->setText(szText); addPage(m_pDesktopIntegration, __tr2qs("Desktop Integration")); #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) m_pCreateUrlHandlers = new QCheckBox(__tr2qs("Make KVIrc the default IRC client"), m_pDesktopIntegration->m_pVBox); m_pCreateUrlHandlers->setChecked(true); #endif #ifdef COMPILE_KDE_SUPPORT m_pCreateDesktopShortcut = new QCheckBox(__tr2qs("Create desktop shortcut"), m_pDesktopIntegration->m_pVBox); m_pCreateDesktopShortcut->setChecked(true); #endif #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) m_pUseMircServerList = new QCheckBox(__tr2qs("Import server list from mIRC"), m_pDesktopIntegration->m_pVBox); m_pUseMircServerList->setEnabled(false); #endif setHelpEnabled(m_pDesktopIntegration, false); setFinishEnabled(m_pDesktopIntegration, true); // Preconfigured values #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) QString szTmp; g_pApp->getGlobalKvircDirectory(szTmp, KviApplication::Config, "preinstalled.kvc"); if(KviFileUtils::fileExists(szTmp)) { KviConfigurationFile cfg(szTmp, KviConfigurationFile::Read); cfg.setGroup("Setup"); if(cfg.readBoolEntry("hideServerList", false)) { //setPageEnabled(m_pServers,false); //setFinishEnabled(m_pIdentity,true); KVI_OPTION_BOOL(KviOption_boolShowChannelsJoinOnIrc) = false; KVI_OPTION_BOOL(KviOption_boolShowServersConnectDialogOnStart) = false; } int iDir; iDir = cfg.readIntEntry("settingsDir", -1); if(iDir > 0) { switch(iDir) { case 1: m_pDirUseNew->toggle(); setPageEnabled(m_pDirectory, false); break; case 2: m_pDirMakePortable->toggle(); setPageEnabled(m_pDirectory, false); break; } } } //mIRC import #define QUERY_BUFFER 2048 char * buffer; DWORD len = QUERY_BUFFER; buffer = (char *)malloc(len * sizeof(char)); HKEY hKey; QString szMircDir; if(RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("ChatFile\\DefaultIcon"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) { if(RegQueryValueEx(hKey, 0, 0, 0, (LPBYTE)buffer, &len) == ERROR_SUCCESS) { szMircDir = QString::fromLocal8Bit(buffer, len); szMircDir.remove('"'); QString szMircFile = KviFileUtils::extractFileName(szMircDir); szMircFile = szMircFile.left(szMircFile.length() - 4); //cut off ".exe" szMircDir = KviFileUtils::extractFilePath(szMircDir); szMircIni = szMircDir + "/" + szMircFile + ".ini"; if(!KviFileUtils::fileExists(szMircIni)) szMircIni = szMircDir + "/mirc.ini"; if(!KviFileUtils::fileExists(szMircIni)) szMircIni = szMircDir + "/pirc.ini"; if(KviFileUtils::fileExists(szMircIni)) { KviConfigurationFile cfg(szMircIni, KviConfigurationFile::Read, true); if(cfg.hasGroup("mirc")) { g_bFoundMirc = true; cfg.setGroup("mirc"); m_pNickSelector->setText(cfg.readEntry("nick", KVI_OPTION_STRING(KviOption_stringNickname1))); m_pRealNameSelector->setText(cfg.readEntry("user", KVI_OPTION_STRING(KviOption_stringRealname))); KVI_OPTION_STRING(KviOption_stringNickname2) = cfg.readEntry("anick", KVI_OPTION_STRING(KviOption_stringNickname2)); KVI_OPTION_STRING(KviOption_stringUsername) = cfg.readEntry("email", KVI_OPTION_STRING(KviOption_stringUsername)).section('@', 0, 0); if(cfg.hasGroup("files")) { m_szMircServerIniFile = cfg.readEntry("servers", "servers.ini"); m_szMircServerIniFile.prepend('/'); m_szMircServerIniFile.prepend(szMircDir); if(KviFileUtils::fileExists(m_szMircServerIniFile)) { m_pUseMircServerList->setEnabled(true); m_pUseMircServerList->setChecked(true); } } } } } } free(buffer); #endif // COMPILE_ON_WINDOWS newDirClicked(); //setMinimumSize(630,450); enableOrDisableIdentityPageNextButton(); } SetupWizard::~SetupWizard() { delete m_pLabelPixmap; } void SetupWizard::showEvent(QShowEvent * e) { QRect r = g_pApp->primaryScreen()->availableGeometry(); int w = r.width(); int h = r.height(); int ww = width(); int wh = height(); if(w < 800) { // 640x480 if(ww < 630) ww = 630; } else { if(ww < 770) ww = 770; } setGeometry(r.left() + (w - ww) / 2, r.top() + (h - wh) / 2, ww, wh); KviTalWizard::showEvent(e); } void SetupWizard::enableOrDisableIdentityPageNextButton() { setNextEnabled(m_pIdentity, !m_pNickSelector->currentText().trimmed().isEmpty()); } void SetupWizard::nickSelectorTextChanged(const QString & str) { enableOrDisableIdentityPageNextButton(); } void SetupWizard::oldDirClicked() { m_pOldPathBox->setEnabled(true); m_pNewPathBox->setEnabled(false); m_pNewIncomingBox->setEnabled(false); if(m_pIdentity) setPageEnabled(m_pIdentity, false); if(m_pTheme) setPageEnabled(m_pTheme, false); if(m_pServers) setPageEnabled(m_pServers, false); if(m_pOldDataPathEdit->text().isEmpty()) setNextEnabled(m_pDirectory, false); else setNextEnabled(m_pDirectory, true); } void SetupWizard::oldDataTextChanged(const QString & str) { setNextEnabled(m_pDirectory, !str.isEmpty()); } void SetupWizard::newDataTextChanged(const QString & str) { setNextEnabled(m_pDirectory, !str.isEmpty() && !m_pIncomingPathEdit->text().isEmpty()); } void SetupWizard::newIncomingTextChanged(const QString & str) { setNextEnabled(m_pDirectory, !str.isEmpty() && !m_pDataPathEdit->text().isEmpty()); } void SetupWizard::newDirClicked() { m_pOldPathBox->setEnabled(false); m_pNewPathBox->setEnabled(true); m_pNewIncomingBox->setEnabled(true); if(m_pIdentity) setPageEnabled(m_pIdentity, true); if(m_pTheme) setPageEnabled(m_pTheme, true); if(m_pServers) setPageEnabled(m_pServers, true); if(m_pDataPathEdit->text().isEmpty() || m_pIncomingPathEdit->text().isEmpty()) setNextEnabled(m_pDirectory, false); else setNextEnabled(m_pDirectory, true); } void SetupWizard::portableClicked() { m_pOldPathBox->setEnabled(false); m_pNewPathBox->setEnabled(false); m_pNewIncomingBox->setEnabled(false); if(m_pIdentity) setPageEnabled(m_pIdentity, true); if(m_pTheme) setPageEnabled(m_pTheme, true); if(m_pServers) setPageEnabled(m_pServers, true); setNextEnabled(m_pDirectory, true); } void SetupWizard::chooseOldDataPath() { // FIXME: We'd like to show hidden directories here ($HOME/.kvirc is hidden)... QString szBuffer = KviTalFileDialog::getExistingDirectoryPath( m_pDataPathEdit->text(), __tr2qs("Choose an Existing Configuration Folder - KVIrc Setup"), this); if(szBuffer.isEmpty()) return; KviFileUtils::adjustFilePath(szBuffer); KviQString::ensureLastCharIs(szBuffer, KVI_PATH_SEPARATOR_CHAR); if(!g_pApp->checkLocalKvircDirectory(szBuffer)) { if( QMessageBox::question( this, __tr2qs("Confirm Setting Configuration Folder - KVIrc Setup"), __tr2qs("The folder %1 doesn't seem to be a valid KVIrc settings folder. Do you want to use it anyway?") .arg(szBuffer)) == QMessageBox::Yes) m_pOldDataPathEdit->setText(szBuffer); } else { m_pOldDataPathEdit->setText(szBuffer); } } void SetupWizard::chooseDataPath() { QString szBuffer = KviTalFileDialog::getExistingDirectoryPath( m_pDataPathEdit->text(), __tr2qs("Choose a Configuration Folder - KVIrc Setup"), this); KviFileUtils::adjustFilePath(szBuffer); if(!szBuffer.isEmpty()) { KviQString::ensureLastCharIs(szBuffer, KVI_PATH_SEPARATOR_CHAR); m_pDataPathEdit->setText(szBuffer); } } void SetupWizard::chooseIncomingPath() { QString szBuffer = KviTalFileDialog::getExistingDirectoryPath( m_pIncomingPathEdit->text(), __tr2qs("Choose a Download Folder - KVIrc Setup"), this); KviFileUtils::adjustFilePath(szBuffer); if(!szBuffer.isEmpty()) { m_pIncomingPathEdit->setText(szBuffer); } } void SetupWizard::makeLink() { #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) // Let's make a link on the desktop :) // You need this horrible snippet of code to create a shortcut!!!! // // you have to: // - dig in the registry, // - trigger the entire COM subsystem // - bring up a couple of OLE interfaces.... // - use some obscure functions like MultiByteToWideChar // - and the finally drop the entire OLE+COM interface in the garbadge // ... // Isn't this horrible ? (compared to symlink()!) // // Well..let's go (please note that we don't handle most possible errors! // otherwise there would be 150 lines for a stupid symlink!) HKEY hCU; DWORD lpType; ULONG ulSize = MAX_PATH; char szLink[MAX_PATH]; // Dig in the registry looking up the Desktop path if(RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), 0, KEY_QUERY_VALUE, &hCU) == ERROR_SUCCESS) { RegQueryValueEx(hCU, TEXT("Desktop"), nullptr, &lpType, (unsigned char *)&szLink, &ulSize); RegCloseKey(hCU); } // Build our paths QString szLinkTarget = szLink; szLinkTarget.append("\\kvirc.lnk"); QString szKvircExec = g_pApp->m_szGlobalKvircDir; szKvircExec.append("\\kvirc.exe"); // Trigger a horrible machinery CoInitialize(nullptr); // we need COM+OLE // Fiddle with an obscure shell interface IShellLink * psl; // Get a pointer to the IShellLink interface: this is kinda ugly :) if(CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl) == S_OK) { // just for fun, lookup another shell interface IPersistFile * ppf; // Query IShellLink for the IPersistFile interface for // saving the shell link in persistent storage. if(psl->QueryInterface(IID_IPersistFile, (void **)&ppf) == S_OK) { WORD wsz[MAX_PATH]; // Set the path to the shell link target. psl->SetPath(szKvircExec.toStdWString().c_str()); // Set the description of the shell link. psl->SetDescription(TEXT("kvirc")); // Ensure string is ANSI. MultiByteToWideChar(CP_ACP, 0, QTextCodec::codecForLocale()->fromUnicode(szLinkTarget).data(), -1, (LPWSTR)wsz, MAX_PATH); // Save the link via the IPersistFile::Save method. ppf->Save((LPCOLESTR)wsz, true); ppf->Release(); } psl->Release(); } // And throw OLE & Co. in the garbadge CoUninitialize(); #endif //COMPILE_ON_WINDOWS #ifdef COMPILE_KDE_SUPPORT QString tmp = QDir::homePath(); KviQString::ensureLastCharIs(tmp, KVI_PATH_SEPARATOR_CHAR); tmp.append("Desktop"); KviQString::ensureLastCharIs(tmp, KVI_PATH_SEPARATOR_CHAR); tmp.append("kvirc.desktop"); QString contents = "[Desktop Entry]\n" "GenericName=IRC Client\n" "Comment=Connect to Internet Relay Chat\n" "Exec=kvirc -m %u\n" "Icon=kvirc\n" "MapNotify=true\n" "Name=KVIrc\n" "Terminal=false\n" "Type=Application\n" "X-KDE-SubstituteUID=false\n"; KviFileUtils::writeFile(tmp, contents, false); #endif //COMPILE_KDE_SUPPORT } void SetupWizard::setUrlHandlers() { #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) QString szReg = "REGEDIT4\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc]\r\n" "@=\"URL:IRC Protocol\"\r\n" "\"IRC Protocol\"=\"http://www.kvirc.net/\"\r\n" "\"EditFlags\"=hex:02,00,00,00\r\n" "\"URL Protocol\"=" "\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc\\DefaultIcon]\r\n" "@=\"\\\"@KVIRCEXECUTABLE@\\\"\"\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc\\shell]\r\n" "@=\"\"\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc\\shell\\open]\r\n" "\"EditFlags\"=hex:01,00,00,00\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc\\shell\\open\\command]\r\n" "@=\"\\\"@KVIRCEXECUTABLE@\\\" %1\"\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc6]\r\n" "@=\"URL:IRC6 Protocol\"\r\n" "\"IRC6 Protocol\"=\"http://www.kvirc.net/\"\r\n" "\"EditFlags\"=hex:02,00,00,00\r\n" "\"URL Protocol\"=" "\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc6\\DefaultIcon]\r\n" "@=\"\\\"@KVIRCEXECUTABLE@\\\"\"\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc6\\shell]\r\n" "@=\"\"\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc6\\shell\\open]\r\n" "\"EditFlags\"=hex:01,00,00,00\r\n" "\r\n" "[HKEY_CLASSES_ROOT\\irc6\\shell\\open\\command]\r\n" "@=\"\\\"@KVIRCEXECUTABLE@\\\" %1\"\r\n"; QString szKvircExec = g_pApp->m_szGlobalKvircDir; szKvircExec.append("\\kvirc.exe"); szKvircExec.replace("\\", "\\\\"); szReg.replace("@KVIRCEXECUTABLE@", QTextCodec::codecForLocale()->fromUnicode(szKvircExec)); QString szRegFile = g_pApp->m_szGlobalKvircDir; szRegFile.append("\\kvirc.reg"); KviFileUtils::writeFile(szRegFile, szReg, false); QString szCmd = "regedit /S \""; szCmd += szRegFile; szCmd += "\""; WinExec(QTextCodec::codecForLocale()->fromUnicode(szCmd).data(), SW_SHOW); #endif } void SetupWizard::reject() { if(QMessageBox::question(this, __tr2qs("Confirm Setup Abort - KVIrc Setup"), __tr2qs("You have chosen to abort the setup.
KVIrc can't run until you complete this procedure.

Do you really wish to abort?")) != QMessageBox::Yes) return; KviTalWizard::reject(); } void SetupWizard::accept() { QString szDir; if(m_pDirUsePrev->isChecked()) { bNeedToApplyDefaults = false; g_pApp->m_szLocalKvircDir = m_pOldDataPathEdit->text(); } else { bNeedToApplyDefaults = true; if(m_pDirUseNew->isChecked()) { szDir = m_pDataPathEdit->text(); } #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) else { //portable szDir = QString("%1%2%3").arg(g_pApp->applicationDirPath()).arg(KVI_PATH_SEPARATOR_CHAR).arg("Settings"); } #endif KviFileUtils::adjustFilePath(szDir); KviQString::ensureLastCharIs(szDir, KVI_PATH_SEPARATOR_CHAR); if(!KviFileUtils::directoryExists(szDir)) { if(!KviFileUtils::makeDir(szDir)) { KviMessageBox::warning(__tr("Can't create directory %s.\n" "You may not have write permission " "for that path. Please go back and choose another directory.")); setCurrentPage(m_pDirectory); return; } } g_pApp->m_szLocalKvircDir = szDir; KviFileUtils::adjustFilePath(g_pApp->m_szLocalKvircDir); if(m_pDirUseNew->isChecked()) { szDir = m_pIncomingPathEdit->text(); } #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) else { //portable szDir = QString("%1%2%3").arg(g_pApp->applicationDirPath()).arg(KVI_PATH_SEPARATOR_CHAR).arg("Downloads"); } #endif KviFileUtils::adjustFilePath(szDir); if(!KviFileUtils::directoryExists(szDir)) { if(!KviFileUtils::makeDir(szDir)) { KviMessageBox::warning(__tr("Can't create directory %s.\n" "You may not have write permission for that path.\n" "Please go back and choose another directory.")); setCurrentPage(m_pDirectory); return; } } g_szChoosenIncomingDirectory = szDir; #if !defined(COMPILE_ON_WINDOWS) && !defined(COMPILE_ON_MINGW) // Make local->global link QString localPath = QString("%1/global").arg(g_pApp->m_szLocalKvircDir); unlink(QTextCodec::codecForLocale()->fromUnicode(localPath).data()); (void)symlink(QTextCodec::codecForLocale()->fromUnicode(g_pApp->m_szGlobalKvircDir).data(), QTextCodec::codecForLocale()->fromUnicode(localPath).data()); #endif #ifdef COMPILE_KDE_SUPPORT if(m_pCreateDesktopShortcut->isChecked()) makeLink(); #endif #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) if(m_pCreateUrlHandlers->isChecked()) setUrlHandlers(); #endif if(m_pTheme) { if(m_pThemeHiRes->isChecked()) { g_iThemeToApply = THEME_APPLY_HIRES; } else if(m_pThemeLoRes->isChecked()) { g_iThemeToApply = THEME_APPLY_LORES; } else { g_iThemeToApply = THEME_APPLY_NONE; } } if(m_pIdentity) { m_pNickSelector->commit(); m_pRealNameSelector->commit(); m_pLocationSelector->commit(); m_pLanguagesSelector->commit(); KVI_OPTION_STRING(KviOption_stringNickname1) = KVI_OPTION_STRING(KviOption_stringNickname1).trimmed(); if(KVI_OPTION_STRING(KviOption_stringNickname1).length() > 32) KVI_OPTION_STRING(KviOption_stringNickname1) .truncate(32); if(KVI_OPTION_STRING(KviOption_stringNickname1).isEmpty()) KVI_OPTION_STRING(KviOption_stringNickname1) = KVI_DEFAULT_NICKNAME1; QString szNickPart; if(KVI_OPTION_STRING(KviOption_stringNickname1).length() < 31) { szNickPart = KVI_OPTION_STRING(KviOption_stringNickname1); } else { szNickPart = KVI_OPTION_STRING(KviOption_stringNickname1).left(30); } if(!g_bFoundMirc) KVI_OPTION_STRING(KviOption_stringNickname2) = QString(KVI_DEFAULT_NICKNAME2).replace(KVI_DEFAULT_NICKNAME_TOKEN, szNickPart); KVI_OPTION_STRING(KviOption_stringNickname3) = QString(KVI_DEFAULT_NICKNAME3).replace(KVI_DEFAULT_NICKNAME_TOKEN, szNickPart); KVI_OPTION_STRING(KviOption_stringNickname4) = QString(KVI_DEFAULT_NICKNAME4).replace(KVI_DEFAULT_NICKNAME_TOKEN, szNickPart); int i = m_pAgeCombo->currentIndex(); if(i < 0) i = 0; if(i > 120) i = 120; if(i <= 0) KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge) = ""; else KVI_OPTION_STRING(KviOption_stringCtcpUserInfoAge) .setNum(i); switch(m_pGenderCombo->currentIndex()) { case 1: // this should be in English KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Female"; break; case 2: // this should be in English KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = "Male"; break; default: KVI_OPTION_STRING(KviOption_stringCtcpUserInfoGender) = ""; break; } #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) if(m_pUseMircServerList->isEnabled() && m_pUseMircServerList->isChecked()) szMircServers = m_szMircServerIniFile; #endif } } #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) if(m_pDirMakePortable->isChecked()) { KviFileUtils::writeFile(QString("%1%2%3").arg(g_pApp->applicationDirPath()).arg(KVI_PATH_SEPARATOR_CHAR).arg("portable"), QString("true")); g_pApp->m_bPortable = true; } else { #endif g_pApp->saveKvircDirectory(); #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) } #endif KviTalWizard::accept(); }