#include "uninstallWidget.h" #include "msgDialog.h" #include "uninstall.h" #include "inputDialog.h" #include #include #include #include #include #include #include "globe.xpm" #include "folder.xpm" #include "user.xpm" #include "theme.xpm" #define ELEMENTS(x) (sizeof (x) / sizeof (x[0])) GtkWidget *mainUninstallTree,*systemMenu,*userMenu; struct stInstalledThemell *selectedInstalledTheme,*global,*local; struct stInstalledThemell *selectedInstalledDir,*movingTheme; char systemInstallPath[PATH_MAX]; char userInstallPath[PATH_MAX]; int globalSelected; int userSelected; static void menuMoveTheme(GtkWidget *,struct stInstalledThemell *); static void menuCreateSubfolder(GtkWidget *,struct stInstalledThemell *); static void removeSubfolder(GtkWidget *,struct stInstalledThemell *); static void userCreateSubfolder(); static void systemCreateSubfolder(); enum { TARGET_URI_LIST }; static GtkTargetEntry dropTypes[]={ {"test/uri-list",0,TARGET_URI_LIST} }; void updateSystemMenu(void); void updateUserMenu(void); /*************** GTK Widget functions on the installed list *****************/ static void installedSelectTreeItem(GtkWidget *item,struct stInstalledThemell *pCurrent) { selectedInstalledTheme=pCurrent; } static void installedDeselectTreeItem(GtkWidget *item,struct stInstalledThemell *pCurrent) { selectedInstalledTheme=NULL; } static void installedSelectDirectory(GtkWidget *item,struct stInstalledThemell *pCurrent) { selectedInstalledTheme=NULL; selectedInstalledDir=pCurrent; } static void globalDirectorySelected() { globalSelected=1; } static void globalDirectoryDeselected() { globalSelected=0; } static void userDirectorySelected() { userSelected=1; } static void userDirectoryDeselected() { userSelected=0; } void useThemeButtonClicked(GtkWidget *button) { char command[2048]; if (selectedInstalledTheme!=NULL) { snprintf(command,2048,"setstyle \"%s\"", selectedInstalledTheme->filename); system(command); } else { showMessageDialog("Error","There is no theme currently\nselected to use."); } } void uninstallThemeButtonClicked(GtkWidget *button) { if (selectedInstalledTheme!=NULL) { uninstallTheme(selectedInstalledTheme); updateInstalledTree(systemInstallPath,userInstallPath); } else { showMessageDialog("Error","There is no theme currently\nselected to uninstall."); } } GtkWidget *createPixLabel(GtkWidget *window,char *pixmapData[],char *labelText) { GtkWidget *hbox; GtkWidget *label; GtkWidget *pixmapWidget; GdkPixmap *pixmap; GdkBitmap *mask; GtkWidget *test; hbox=gtk_hbox_new(FALSE,0); if (pixmapData!=NULL) { pixmap=gdk_pixmap_create_from_xpm_d(window->window,&mask, NULL,pixmapData); pixmapWidget=gtk_pixmap_new(pixmap,mask); gtk_box_pack_start(GTK_BOX(hbox),pixmapWidget,FALSE,FALSE,0); gtk_widget_show(pixmapWidget); } label=gtk_label_new(labelText); gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); gtk_widget_show(label); gtk_widget_show(hbox); return hbox; } /********************* Right button click stuff **********************/ void uninstallPopup(GtkWidget *widget,struct stInstalledThemell *current) { GtkWidget *item; item=current->widget; uninstallTheme(current); refreshInstalledTree(); } void popupChangeTo(GtkWidget *widget,struct stInstalledThemell *current) { char command[2048]; if (current!=NULL) { snprintf(command,2048,"setstyle \"%s\"", current->filename); system(command); } else { showMessageDialog("Error","There is no theme currently\nselected to use."); } } void themeButtonPress(GtkWidget *widget,GdkEventButton *event, struct stInstalledThemell *current) { GtkWidget *menu; GtkWidget *menuItem; if (current&&(event->button==3)) { /* This is where we need to handle the popup menu */ menu=gtk_menu_new(); menuItem=gtk_menu_item_new_with_label("Change to..."); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(popupChangeTo),current); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); menuItem=gtk_menu_item_new_with_label("Move to..."); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(menuMoveTheme),current); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); menuItem=gtk_menu_item_new_with_label("Uninstall"); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(uninstallPopup),current); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,event->button, event->time); } } void folderButtonPress(GtkWidget *widget,GdkEventButton *event, struct stInstalledThemell *current) { GtkWidget *menu; GtkWidget *menuItem; if (current&&(event->button==3)) { menu=gtk_menu_new(); menuItem=gtk_menu_item_new_with_label("Create subfolder..."); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(menuCreateSubfolder),current); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); if (current->child==NULL) { menuItem=gtk_menu_item_new_with_label("Remove folder"); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(removeSubfolder),current); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); } gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,event->button, event->time); } } void userButtonPress(GtkWidget *widget,GdkEventButton *event) { GtkWidget *menu; GtkWidget *menuItem; if (event->button==3) { menu=gtk_menu_new(); menuItem=gtk_menu_item_new_with_label("Create subfoler..."); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(userCreateSubfolder),NULL); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,event->button, event->time); } } void systemButtonPress(GtkWidget *widget,GdkEventButton *event) { GtkWidget *menu; GtkWidget *menuItem; if (event->button==3) { menu=gtk_menu_new(); menuItem=gtk_menu_item_new_with_label("Create subfoler..."); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(systemCreateSubfolder),NULL); gtk_menu_append(GTK_MENU(menu),menuItem); gtk_widget_show(menuItem); gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,event->button, event->time); } } /******************* Drag and drop stuff *******************/ void installedDragDataGet(GtkWidget *temp,GdkDragContext *context, GtkSelectionData *selData,gint info,guint tinm,gpointer data) { if (data) printf("%s\n",((struct stInstalledThemell *)data)->name); } static void setDraggable(GtkWidget *dragit,char *pixmapData[], struct stInstalledThemell *data) { GdkBitmap *mask; GdkPixmap *pixmap; GdkColormap *colormap; pixmap=gdk_pixmap_create_from_xpm_d(dragit->window,&mask, NULL,pixmapData); colormap=dragit->style->colormap; gtk_drag_dest_set(dragit,GTK_DEST_DEFAULT_ALL, dropTypes,ELEMENTS(dropTypes), GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); gtk_drag_source_set(dragit,GDK_BUTTON1_MASK,dropTypes, ELEMENTS(dropTypes), GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); gtk_drag_source_set_icon(dragit,colormap,pixmap,mask); /* gtk_signal_connect(GTK_OBJECT(dragit),"event", GTK_SIGNAL_FUNC(gotEvent),(gpointer)data);*/ } /************************ Widget Creation *************************/ void fillInstalledWidgetTree(GtkWidget *tree,struct stInstalledThemell *first) { GtkWidget *item; struct stInstalledThemell *current=first; while (current!=NULL) { item=gtk_tree_item_new(); gtk_tree_append(GTK_TREE(tree),item); gtk_widget_show(item); current->widget=item; if (current->themeType==DIRECTORY) { GtkWidget *subtree; GtkWidget *pixLabel; pixLabel=createPixLabel(item,folder_xpm,current->name); gtk_container_add(GTK_CONTAINER(item),pixLabel); gtk_signal_connect(GTK_OBJECT(item),"select", GTK_SIGNAL_FUNC(installedSelectDirectory), current); gtk_signal_connect(GTK_OBJECT(item),"button-press-event", GTK_SIGNAL_FUNC(folderButtonPress),current); subtree=gtk_tree_new(); gtk_tree_item_set_subtree(GTK_TREE_ITEM(item),subtree); fillInstalledWidgetTree(subtree,current->child); } else { gtk_container_add(GTK_CONTAINER(item),createPixLabel(item,theme_xpm,current->name)); gtk_signal_connect(GTK_OBJECT(item),"select", GTK_SIGNAL_FUNC(installedSelectTreeItem), current); gtk_signal_connect(GTK_OBJECT(item),"deselect", GTK_SIGNAL_FUNC(installedDeselectTreeItem), current); gtk_signal_connect(GTK_OBJECT(item),"button-press-event", GTK_SIGNAL_FUNC(themeButtonPress),current); // setDraggable(item,theme_xpm,current); } current=current->next; } } void refreshInstalledTree() { updateInstalledTree(systemInstallPath,userInstallPath); } void updateInstalledTree(char *systemPath,char *userPath) { GtkWidget *item,*subtree; global=getInstalledList(systemPath,GLOBAL_INSTALL); local=getInstalledList(userPath,LOCAL_INSTALL); strncpy(systemInstallPath,systemPath,PATH_MAX); strncpy(userInstallPath,userPath,PATH_MAX); if (mainUninstallTree==NULL) { printf("The main installed tree does not exist!\n"); return; } gtk_tree_remove_items(GTK_TREE(mainUninstallTree),(GTK_TREE(mainUninstallTree))->children); if (global!=NULL) { item=gtk_tree_item_new(); gtk_tree_append(GTK_TREE(mainUninstallTree),item); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(item),createPixLabel(item,globe_xpm,"System")); gtk_signal_connect(GTK_OBJECT(item),"select", GTK_SIGNAL_FUNC(globalDirectorySelected),NULL); gtk_signal_connect(GTK_OBJECT(item),"deselect", GTK_SIGNAL_FUNC(globalDirectoryDeselected),NULL); gtk_signal_connect(GTK_OBJECT(item),"button_press_event", GTK_SIGNAL_FUNC(systemButtonPress),NULL); subtree=gtk_tree_new(); gtk_tree_item_set_subtree(GTK_TREE_ITEM(item),subtree); fillInstalledWidgetTree(subtree,global); gtk_tree_item_expand(GTK_TREE_ITEM(item)); } item=gtk_tree_item_new(); gtk_tree_append(GTK_TREE(mainUninstallTree),item); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(item),createPixLabel(item,user_xpm,"User")); gtk_signal_connect(GTK_OBJECT(item),"select", GTK_SIGNAL_FUNC(userDirectorySelected),NULL); gtk_signal_connect(GTK_OBJECT(item),"deselect", GTK_SIGNAL_FUNC(userDirectoryDeselected),NULL); gtk_signal_connect(GTK_OBJECT(item),"button_press_event", GTK_SIGNAL_FUNC(userButtonPress),NULL); subtree=gtk_tree_new(); gtk_tree_item_set_subtree(GTK_TREE_ITEM(item),subtree); fillInstalledWidgetTree(subtree,local); gtk_tree_item_expand(GTK_TREE_ITEM(item)); selectedInstalledTheme=NULL; updateSystemMenu(); updateUserMenu(); } GtkWidget *createInstalledWidget() { GtkWidget *vbox; GtkWidget *label; GtkWidget *scrolledWindow,*tree; GtkWidget *useThemeButton; GtkWidget *uninstallThemeButton; vbox=gtk_vbox_new(FALSE,0); gtk_widget_show(vbox); label=gtk_label_new("Installed WindowMaker Themes"); gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); gtk_widget_show(label); useThemeButton=gtk_button_new_with_label("Use Selected Theme"); gtk_box_pack_start(GTK_BOX(vbox),useThemeButton,FALSE,TRUE,0); gtk_widget_show(useThemeButton); gtk_signal_connect(GTK_OBJECT(useThemeButton),"clicked", GTK_SIGNAL_FUNC(useThemeButtonClicked),NULL); /* Create the scrolled widget */ scrolledWindow=gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox),scrolledWindow,TRUE,TRUE,5); gtk_widget_show(scrolledWindow); /* Create the root tree */ tree=gtk_tree_new(); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledWindow), tree); gtk_tree_set_selection_mode(GTK_TREE(tree),GTK_SELECTION_SINGLE); gtk_widget_show(tree); mainUninstallTree=tree; uninstallThemeButton=gtk_button_new_with_label("Uninstall Selected Theme"); gtk_box_pack_start(GTK_BOX(vbox),uninstallThemeButton,FALSE,TRUE,0); gtk_widget_show(uninstallThemeButton); gtk_signal_connect(GTK_OBJECT(uninstallThemeButton),"clicked", GTK_SIGNAL_FUNC(uninstallThemeButtonClicked),NULL); return vbox; } struct stInstalledThemell *getSelectedInstalledTheme(void) { return selectedInstalledTheme; } struct stInstalledThemell *checkForParent(struct stInstalledThemell *startTheme, struct stInstalledThemell *checkTheme) { struct stInstalledThemell *current,*temp; current=startTheme; while (current!=NULL) { if (current->child==checkTheme) { return current; } if (current->child) { temp=checkForParent(current->child,checkTheme); if (temp) return (temp); } current=current->next; } return NULL; } void getInstalledDirectory(char *directory) { struct stInstalledThemell *current,*temp,*start,*first; char tempDir[PATH_MAX]; memset(tempDir,0,PATH_MAX); memset(directory,0,PATH_MAX); current=selectedInstalledTheme; if (current==NULL) { current=selectedInstalledDir; if (current) snprintf(directory,PATH_MAX,"%s",current->name); } if (globalSelected) { strncpy(directory,systemInstallPath,PATH_MAX); return; } if (userSelected) { strncpy(directory,userInstallPath,PATH_MAX); return; } if (current==NULL) { strcpy(directory,""); return; } if (current->installType==GLOBAL_INSTALL) start=global; if (current->installType==LOCAL_INSTALL) start=local; first=current; while (current!=NULL) { if (current->prev==NULL) { temp=checkForParent(start,current); if (temp) { snprintf(tempDir,PATH_MAX,"%s/%s",temp->name,directory); strncpy(directory,tempDir,PATH_MAX); current=temp; } } if (current) current=current->prev; } if (first->installType==GLOBAL_INSTALL) { snprintf(tempDir,PATH_MAX,"%s/%s",systemInstallPath,directory); strncpy(directory,tempDir,PATH_MAX); } if (first->installType==LOCAL_INSTALL) { snprintf(tempDir,PATH_MAX,"%s/%s",userInstallPath,directory); strncpy(directory,tempDir,PATH_MAX); } } /*************************** Theme moving functions ********************/ void moveOldTheme(char *newFilename) { FILE *fin,*fout; char buffer[4096]; int numread; fin=fopen(movingTheme->filename,"r"); if (fin==NULL) { showMessageDialog("Error","Unable to open source theme"); return; } fout=fopen(newFilename,"w"); if (fout==NULL) { showMessageDialog("Error","Unable to write to destination"); fclose(fin); return; } numread=sizeof(buffer); while (numread==sizeof(buffer)) { numread=fread(buffer,1,sizeof(buffer),fin); fwrite(buffer,1,numread,fout); } fclose(fin); fclose(fout); unlink(movingTheme->filename); } void moveNewTheme(char *newPath) { FILE *fin,*fout; char buffer[4096]; int numread; DIR *dir; struct dirent *entry; char newName[PATH_MAX]; char inFilename[PATH_MAX]; char outFilename[PATH_MAX]; int error; snprintf(newName,PATH_MAX,"%s.themed/",newPath); error=mkdir(newName,0777); if (error) { showMessageDialog("Error","Unable to create new directory"); return; } dir=opendir(movingTheme->filename); if (dir==NULL) { showMessageDialog("Error","Unable to open source directory"); unlink(newName); return; } while ((entry=readdir(dir))!=NULL) { if (strcmp(entry->d_name,".")&&strcmp(entry->d_name,"..")) { snprintf(inFilename,PATH_MAX,"%s/%s",movingTheme->filename, entry->d_name); snprintf(outFilename,PATH_MAX,"%s%s",newName,entry->d_name); fin=fopen(inFilename,"r"); fout=fopen(outFilename,"w"); numread=sizeof(buffer); while (numread==sizeof(buffer)) { numread=fread(buffer,1,sizeof(buffer),fin); fwrite(buffer,1,numread,fout); } fclose(fin); fclose(fout); unlink(inFilename); } } closedir(dir); rmdir(movingTheme->filename); } /*************************** Menu Signal Functions *********************/ static void moveThemeReturned(char *newpath) { char newFilename[PATH_MAX]; snprintf(newFilename,PATH_MAX,"%s%s",newpath,movingTheme->name); if (movingTheme->themeType==OLD_THEME) moveOldTheme(newFilename); if (movingTheme->themeType==NEW_THEME) moveNewTheme(newFilename); refreshInstalledTree(); } static void menuMoveTheme(GtkWidget *widget, struct stInstalledThemell *current) { char fullpath[PATH_MAX]; movingTheme=current; if (current->installType==GLOBAL_INSTALL) { snprintf(fullpath,PATH_MAX,"%s/anything",systemInstallPath); } else { snprintf(fullpath,PATH_MAX,"%s/anything",userInstallPath); } showThemeDirBrowser(GTK_SIGNAL_FUNC(moveThemeReturned), fullpath); } static void removeSubfolder(GtkWidget *widget, struct stInstalledThemell *current) { int error; error=rmdir(current->filename); if (error) { showMessageDialog("Error","Unable to remove folder"); } else { refreshInstalledTree(); } } static void createSubfolderReturn(char *path) { int error; error=mkdir(path,0777); if (error) { showMessageDialog("Error","Unable to create folder"); } else { refreshInstalledTree(); } } static void menuCreateSubfolder(GtkWidget *widget, struct stInstalledThemell *current) { char fullPath[PATH_MAX]; snprintf(fullPath,PATH_MAX,"%s/",current->filename); showInputDialog(GTK_SIGNAL_FUNC(createSubfolderReturn), "New Folder Name","Name: ",fullPath); } static void systemCreateSubfolder() { char fullPath[PATH_MAX]; snprintf(fullPath,PATH_MAX,"%s/",systemInstallPath); showInputDialog(GTK_SIGNAL_FUNC(createSubfolderReturn), "New Folder Name","Name: ",fullPath); } static void userCreateSubfolder() { char fullPath[PATH_MAX]; snprintf(fullPath,PATH_MAX,"%s/",userInstallPath); showInputDialog(GTK_SIGNAL_FUNC(createSubfolderReturn), "New Folder Name","Name: ",fullPath); } /*************************** Menu update functions *********************/ void setSystemMenu(GtkWidget *menu) { systemMenu=menu; } void setUserMenu(GtkWidget *menu) { userMenu=menu; } void addThemeSubmenu(GtkWidget *menu,struct stInstalledThemell *first) { char menuName[256]; struct stInstalledThemell *current; GtkWidget *submenu; GtkWidget *menuItem; current=first; while (current!=NULL) { if (current->themeType==DIRECTORY) strncpy(menuName,current->name,256); else snprintf(menuName,256,"Move %s",current->name); menuItem=gtk_menu_item_new_with_label(menuName); gtk_widget_show(menuItem); gtk_menu_append(GTK_MENU(menu),menuItem); if (current->themeType==DIRECTORY) { submenu=gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuItem),submenu); if (current->child==NULL) { menuItem=gtk_menu_item_new_with_label("Remove Folder"); gtk_widget_show(menuItem); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(removeSubfolder),current); gtk_menu_append(GTK_MENU(submenu),menuItem); } menuItem=gtk_menu_item_new_with_label("Create subfolder..."); gtk_widget_show(menuItem); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(menuCreateSubfolder),current); gtk_menu_append(GTK_MENU(submenu),menuItem); if (current->child) { addSeparator(submenu); addThemeSubmenu(submenu,current->child); } } else { gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(menuMoveTheme),current); } current=current->next; } } void updateSystemMenu() { GtkWidget *menu; GtkWidget *menuItem; gtk_widget_show(systemMenu); menu=gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(systemMenu),menu); menuItem=gtk_menu_item_new_with_label("Create subfolder..."); gtk_widget_show(menuItem); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(systemCreateSubfolder),NULL); gtk_menu_append(GTK_MENU(menu),menuItem); addSeparator(menu); addThemeSubmenu(menu,global); } void updateUserMenu() { GtkWidget *menu; GtkWidget *menuItem; gtk_widget_show(userMenu); menu=gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(userMenu),menu); menuItem=gtk_menu_item_new_with_label("Create subfolder..."); gtk_widget_show(menuItem); gtk_signal_connect(GTK_OBJECT(menuItem),"activate", GTK_SIGNAL_FUNC(userCreateSubfolder),NULL); gtk_menu_append(GTK_MENU(menu),menuItem); addSeparator(menu); addThemeSubmenu(menu,local); }